LCOV - code coverage report
Current view: top level - g10 - keyedit.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 291 3051 9.5 %
Date: 2016-11-29 15:00:56 Functions: 8 61 13.1 %

          Line data    Source code
       1             : /* keyedit.c - Edit properties of a key
       2             :  * Copyright (C) 1998-2010 Free Software Foundation, Inc.
       3             :  * Copyright (C) 1998-2016 Werner Koch
       4             :  * Copyright (C) 2015, 2016 g10 Code GmbH
       5             :  *
       6             :  * This file is part of GnuPG.
       7             :  *
       8             :  * GnuPG is free software; you can redistribute it and/or modify
       9             :  * it under the terms of the GNU General Public License as published by
      10             :  * the Free Software Foundation; either version 3 of the License, or
      11             :  * (at your option) any later version.
      12             :  *
      13             :  * GnuPG is distributed in the hope that it will be useful,
      14             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      15             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      16             :  * GNU General Public License for more details.
      17             :  *
      18             :  * You should have received a copy of the GNU General Public License
      19             :  * along with this program; if not, see <https://www.gnu.org/licenses/>.
      20             :  */
      21             : 
      22             : #include <config.h>
      23             : #include <stdio.h>
      24             : #include <stdlib.h>
      25             : #include <string.h>
      26             : #include <errno.h>
      27             : #include <ctype.h>
      28             : #ifdef HAVE_LIBREADLINE
      29             : # define GNUPG_LIBREADLINE_H_INCLUDED
      30             : # include <readline/readline.h>
      31             : #endif
      32             : 
      33             : #include "gpg.h"
      34             : #include "options.h"
      35             : #include "packet.h"
      36             : #include "status.h"
      37             : #include "iobuf.h"
      38             : #include "keydb.h"
      39             : #include "photoid.h"
      40             : #include "util.h"
      41             : #include "main.h"
      42             : #include "trustdb.h"
      43             : #include "filter.h"
      44             : #include "ttyio.h"
      45             : #include "status.h"
      46             : #include "i18n.h"
      47             : #include "keyserver-internal.h"
      48             : #include "call-agent.h"
      49             : #include "host2net.h"
      50             : #include "tofu.h"
      51             : 
      52             : static void show_prefs (PKT_user_id * uid, PKT_signature * selfsig,
      53             :                         int verbose);
      54             : static void show_names (ctrl_t ctrl, estream_t fp,
      55             :                         kbnode_t keyblock, PKT_public_key * pk,
      56             :                         unsigned int flag, int with_prefs);
      57             : static void show_key_with_all_names (ctrl_t ctrl, estream_t fp,
      58             :                                      KBNODE keyblock, int only_marked,
      59             :                                      int with_revoker, int with_fpr,
      60             :                                      int with_subkeys, int with_prefs,
      61             :                                      int nowarn);
      62             : static void show_key_and_fingerprint (kbnode_t keyblock, int with_subkeys);
      63             : static void show_key_and_grip (kbnode_t keyblock);
      64             : static void subkey_expire_warning (kbnode_t keyblock);
      65             : static int menu_adduid (ctrl_t ctrl, kbnode_t keyblock,
      66             :                         int photo, const char *photo_name, const char *uidstr);
      67             : static void menu_deluid (KBNODE pub_keyblock);
      68             : static int menu_delsig (KBNODE pub_keyblock);
      69             : static int menu_clean (KBNODE keyblock, int self_only);
      70             : static void menu_delkey (KBNODE pub_keyblock);
      71             : static int menu_addrevoker (ctrl_t ctrl, kbnode_t pub_keyblock, int sensitive);
      72             : static int menu_expire (KBNODE pub_keyblock);
      73             : static int menu_changeusage (kbnode_t keyblock);
      74             : static int menu_backsign (KBNODE pub_keyblock);
      75             : static int menu_set_primary_uid (KBNODE pub_keyblock);
      76             : static int menu_set_preferences (KBNODE pub_keyblock);
      77             : static int menu_set_keyserver_url (const char *url, KBNODE pub_keyblock);
      78             : static int menu_set_notation (const char *string, KBNODE pub_keyblock);
      79             : static int menu_select_uid (KBNODE keyblock, int idx);
      80             : static int menu_select_uid_namehash (KBNODE keyblock, const char *namehash);
      81             : static int menu_select_key (KBNODE keyblock, int idx, char *p);
      82             : static int count_uids (KBNODE keyblock);
      83             : static int count_uids_with_flag (KBNODE keyblock, unsigned flag);
      84             : static int count_keys_with_flag (KBNODE keyblock, unsigned flag);
      85             : static int count_selected_uids (KBNODE keyblock);
      86             : static int real_uids_left (KBNODE keyblock);
      87             : static int count_selected_keys (KBNODE keyblock);
      88             : static int menu_revsig (KBNODE keyblock);
      89             : static int menu_revuid (ctrl_t ctrl, kbnode_t keyblock);
      90             : static int core_revuid (ctrl_t ctrl, kbnode_t keyblock, KBNODE node,
      91             :                         const struct revocation_reason_info *reason,
      92             :                         int *modified);
      93             : static int menu_revkey (KBNODE pub_keyblock);
      94             : static int menu_revsubkey (KBNODE pub_keyblock);
      95             : #ifndef NO_TRUST_MODELS
      96             : static int enable_disable_key (KBNODE keyblock, int disable);
      97             : #endif /*!NO_TRUST_MODELS*/
      98             : static void menu_showphoto (ctrl_t ctrl, kbnode_t keyblock);
      99             : 
     100             : static int update_trust = 0;
     101             : 
     102             : #define CONTROL_D ('D' - 'A' + 1)
     103             : 
     104             : #define NODFLG_BADSIG (1<<0)      /* Bad signature.  */
     105             : #define NODFLG_NOKEY  (1<<1)      /* No public key.  */
     106             : #define NODFLG_SIGERR (1<<2)      /* Other sig error.  */
     107             : 
     108             : #define NODFLG_MARK_A (1<<4)      /* Temporary mark.  */
     109             : #define NODFLG_DELSIG (1<<5)      /* To be deleted.  */
     110             : 
     111             : #define NODFLG_SELUID (1<<8)      /* Indicate the selected userid. */
     112             : #define NODFLG_SELKEY (1<<9)      /* Indicate the selected key.  */
     113             : #define NODFLG_SELSIG (1<<10)     /* Indicate a selected signature.  */
     114             : 
     115             : struct sign_attrib
     116             : {
     117             :   int non_exportable, non_revocable;
     118             :   struct revocation_reason_info *reason;
     119             :   byte trust_depth, trust_value;
     120             :   char *trust_regexp;
     121             : };
     122             : 
     123             : 
     124             : 
     125             : /* TODO: Fix duplicated code between here and the check-sigs/list-sigs
     126             :    code in keylist.c. */
     127             : static int
     128           0 : print_and_check_one_sig_colon (KBNODE keyblock, KBNODE node,
     129             :                                int *inv_sigs, int *no_key, int *oth_err,
     130             :                                int *is_selfsig, int print_without_key)
     131             : {
     132           0 :   PKT_signature *sig = node->pkt->pkt.signature;
     133             :   int rc, sigrc;
     134             : 
     135             :   /* TODO: Make sure a cached sig record here still has the pk that
     136             :      issued it.  See also keylist.c:list_keyblock_print */
     137             : 
     138           0 :   rc = check_key_signature (keyblock, node, is_selfsig);
     139           0 :   switch (gpg_err_code (rc))
     140             :     {
     141             :     case 0:
     142           0 :       node->flag &= ~(NODFLG_BADSIG | NODFLG_NOKEY | NODFLG_SIGERR);
     143           0 :       sigrc = '!';
     144           0 :       break;
     145             :     case GPG_ERR_BAD_SIGNATURE:
     146           0 :       node->flag = NODFLG_BADSIG;
     147           0 :       sigrc = '-';
     148           0 :       if (inv_sigs)
     149           0 :         ++ * inv_sigs;
     150           0 :       break;
     151             :     case GPG_ERR_NO_PUBKEY:
     152             :     case GPG_ERR_UNUSABLE_PUBKEY:
     153           0 :       node->flag = NODFLG_NOKEY;
     154           0 :       sigrc = '?';
     155           0 :       if (no_key)
     156           0 :         ++ * no_key;
     157           0 :       break;
     158             :     default:
     159           0 :       node->flag = NODFLG_SIGERR;
     160           0 :       sigrc = '%';
     161           0 :       if (oth_err)
     162           0 :         ++ * oth_err;
     163           0 :       break;
     164             :     }
     165             : 
     166           0 :   if (sigrc != '?' || print_without_key)
     167             :     {
     168           0 :       es_printf ("sig:%c::%d:%08lX%08lX:%lu:%lu:",
     169           0 :                  sigrc, sig->pubkey_algo, (ulong) sig->keyid[0],
     170           0 :                  (ulong) sig->keyid[1], (ulong) sig->timestamp,
     171           0 :                  (ulong) sig->expiredate);
     172             : 
     173           0 :       if (sig->trust_depth || sig->trust_value)
     174           0 :         es_printf ("%d %d", sig->trust_depth, sig->trust_value);
     175             : 
     176           0 :       es_printf (":");
     177             : 
     178           0 :       if (sig->trust_regexp)
     179           0 :         es_write_sanitized (es_stdout,
     180           0 :                             sig->trust_regexp, strlen (sig->trust_regexp),
     181             :                             ":", NULL);
     182             : 
     183           0 :       es_printf ("::%02x%c\n", sig->sig_class,
     184           0 :                  sig->flags.exportable ? 'x' : 'l');
     185             : 
     186           0 :       if (opt.show_subpackets)
     187           0 :         print_subpackets_colon (sig);
     188             :     }
     189             : 
     190           0 :   return (sigrc == '!');
     191             : }
     192             : 
     193             : 
     194             : /*
     195             :  * Print information about a signature (rc is its status), check it
     196             :  * and return true if the signature is okay.  NODE must be a signature
     197             :  * packet.  With EXTENDED set all possible signature list options will
     198             :  * always be printed.
     199             :  */
     200             : static int
     201           0 : print_one_sig (int rc, KBNODE keyblock, KBNODE node,
     202             :                int *inv_sigs, int *no_key, int *oth_err,
     203             :                int is_selfsig, int print_without_key, int extended)
     204             : {
     205           0 :   PKT_signature *sig = node->pkt->pkt.signature;
     206             :   int sigrc;
     207           0 :   int is_rev = sig->sig_class == 0x30;
     208             : 
     209             :   /* TODO: Make sure a cached sig record here still has the pk that
     210             :      issued it.  See also keylist.c:list_keyblock_print */
     211             : 
     212           0 :   switch (gpg_err_code (rc))
     213             :     {
     214             :     case 0:
     215           0 :       node->flag &= ~(NODFLG_BADSIG | NODFLG_NOKEY | NODFLG_SIGERR);
     216           0 :       sigrc = '!';
     217           0 :       break;
     218             :     case GPG_ERR_BAD_SIGNATURE:
     219           0 :       node->flag = NODFLG_BADSIG;
     220           0 :       sigrc = '-';
     221           0 :       if (inv_sigs)
     222           0 :         ++ * inv_sigs;
     223           0 :       break;
     224             :     case GPG_ERR_NO_PUBKEY:
     225             :     case GPG_ERR_UNUSABLE_PUBKEY:
     226           0 :       node->flag = NODFLG_NOKEY;
     227           0 :       sigrc = '?';
     228           0 :       if (no_key)
     229           0 :         ++ * no_key;
     230           0 :       break;
     231             :     default:
     232           0 :       node->flag = NODFLG_SIGERR;
     233           0 :       sigrc = '%';
     234           0 :       if (oth_err)
     235           0 :         ++ * oth_err;
     236           0 :       break;
     237             :     }
     238           0 :   if (sigrc != '?' || print_without_key)
     239             :     {
     240           0 :       tty_printf ("%s%c%c %c%c%c%c%c%c %s %s",
     241             :                   is_rev ? "rev" : "sig", sigrc,
     242           0 :                   (sig->sig_class - 0x10 > 0 &&
     243           0 :                    sig->sig_class - 0x10 <
     244           0 :                    4) ? '0' + sig->sig_class - 0x10 : ' ',
     245           0 :                   sig->flags.exportable ? ' ' : 'L',
     246           0 :                   sig->flags.revocable ? ' ' : 'R',
     247           0 :                   sig->flags.policy_url ? 'P' : ' ',
     248           0 :                   sig->flags.notation ? 'N' : ' ',
     249           0 :                   sig->flags.expired ? 'X' : ' ',
     250           0 :                   (sig->trust_depth > 9) ? 'T' : (sig->trust_depth >
     251           0 :                                                   0) ? '0' +
     252           0 :                   sig->trust_depth : ' ',
     253           0 :                   keystr (sig->keyid),
     254             :                   datestr_from_sig (sig));
     255           0 :       if ((opt.list_options & LIST_SHOW_SIG_EXPIRE) || extended )
     256           0 :         tty_printf (" %s", expirestr_from_sig (sig));
     257           0 :       tty_printf ("  ");
     258           0 :       if (sigrc == '%')
     259           0 :         tty_printf ("[%s] ", gpg_strerror (rc));
     260           0 :       else if (sigrc == '?')
     261             :         ;
     262           0 :       else if (is_selfsig)
     263             :         {
     264           0 :           tty_printf (is_rev ? _("[revocation]") : _("[self-signature]"));
     265           0 :           if (extended && sig->flags.chosen_selfsig)
     266           0 :             tty_printf ("*");
     267             :         }
     268             :       else
     269             :         {
     270             :           size_t n;
     271           0 :           char *p = get_user_id (sig->keyid, &n);
     272           0 :           tty_print_utf8_string2 (NULL, p, n,
     273           0 :                                   opt.screen_columns - keystrlen () - 26 -
     274           0 :                                   ((opt.
     275           0 :                                     list_options & LIST_SHOW_SIG_EXPIRE) ? 11
     276             :                                    : 0));
     277           0 :           xfree (p);
     278             :         }
     279           0 :       tty_printf ("\n");
     280             : 
     281           0 :       if (sig->flags.policy_url
     282           0 :           && ((opt.list_options & LIST_SHOW_POLICY_URLS) || extended))
     283           0 :         show_policy_url (sig, 3, 0);
     284             : 
     285           0 :       if (sig->flags.notation
     286           0 :           && ((opt.list_options & LIST_SHOW_NOTATIONS) || extended))
     287           0 :         show_notation (sig, 3, 0,
     288           0 :                        ((opt.
     289           0 :                          list_options & LIST_SHOW_STD_NOTATIONS) ? 1 : 0) +
     290           0 :                        ((opt.
     291           0 :                          list_options & LIST_SHOW_USER_NOTATIONS) ? 2 : 0));
     292             : 
     293           0 :       if (sig->flags.pref_ks
     294           0 :           && ((opt.list_options & LIST_SHOW_KEYSERVER_URLS) || extended))
     295           0 :         show_keyserver_url (sig, 3, 0);
     296             : 
     297           0 :       if (extended)
     298             :         {
     299           0 :           PKT_public_key *pk = keyblock->pkt->pkt.public_key;
     300             :           const unsigned char *s;
     301             : 
     302           0 :           s = parse_sig_subpkt (sig->hashed, SIGSUBPKT_PRIMARY_UID, NULL);
     303           0 :           if (s && *s)
     304           0 :             tty_printf ("             [primary]\n");
     305             : 
     306           0 :           s = parse_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE, NULL);
     307           0 :           if (s && buf32_to_u32 (s))
     308           0 :             tty_printf ("             [expires: %s]\n",
     309           0 :                         isotimestamp (pk->timestamp + buf32_to_u32 (s)));
     310             :         }
     311             :     }
     312             : 
     313           0 :   return (sigrc == '!');
     314             : }
     315             : 
     316             : 
     317             : static int
     318           0 : print_and_check_one_sig (KBNODE keyblock, KBNODE node,
     319             :                          int *inv_sigs, int *no_key, int *oth_err,
     320             :                          int *is_selfsig, int print_without_key, int extended)
     321             : {
     322             :   int rc;
     323             : 
     324           0 :   rc = check_key_signature (keyblock, node, is_selfsig);
     325           0 :   return print_one_sig (rc,
     326             :                         keyblock, node, inv_sigs, no_key, oth_err,
     327             :                         *is_selfsig, print_without_key, extended);
     328             : }
     329             : 
     330             : 
     331             : 
     332             : /* Order two signatures.  The actual ordering isn't important.  Our
     333             :    goal is to ensure that identical signatures occur together.  */
     334             : static int
     335           6 : sig_comparison (const void *av, const void *bv)
     336             : {
     337           6 :   const KBNODE an = *(const KBNODE *) av;
     338           6 :   const KBNODE bn = *(const KBNODE *) bv;
     339             :   const PKT_signature *a;
     340             :   const PKT_signature *b;
     341             :   int ndataa;
     342             :   int ndatab;
     343             :   int i;
     344             : 
     345           6 :   log_assert (an->pkt->pkttype == PKT_SIGNATURE);
     346           6 :   log_assert (bn->pkt->pkttype == PKT_SIGNATURE);
     347             : 
     348           6 :   a = an->pkt->pkt.signature;
     349           6 :   b = bn->pkt->pkt.signature;
     350             : 
     351           6 :   if (a->digest_algo < b->digest_algo)
     352           0 :     return -1;
     353           6 :   if (a->digest_algo > b->digest_algo)
     354           0 :     return 1;
     355             : 
     356           6 :   ndataa = pubkey_get_nsig (a->pubkey_algo);
     357           6 :   ndatab = pubkey_get_nsig (b->pubkey_algo);
     358           6 :   if (ndataa != ndatab)
     359           0 :     return (ndataa < ndatab)? -1 : 1;
     360             : 
     361           6 :   for (i = 0; i < ndataa; i ++)
     362             :     {
     363           6 :       int c = gcry_mpi_cmp (a->data[i], b->data[i]);
     364           6 :       if (c != 0)
     365           6 :         return c;
     366             :     }
     367             : 
     368             :   /* Okay, they are equal.  */
     369           0 :   return 0;
     370             : }
     371             : 
     372             : /* Perform a few sanity checks on a keyblock is okay and possibly
     373             :    repair some damage.  Concretely:
     374             : 
     375             :      - Detect duplicate signatures and remove them.
     376             : 
     377             :      - Detect out of order signatures and relocate them (e.g., a sig
     378             :        over user id X located under subkey Y).
     379             : 
     380             :    Note: this function does not remove signatures that don't belong or
     381             :    components that are not signed!  (Although it would be trivial to
     382             :    do so.)
     383             : 
     384             :    If ONLY_SELFSIGS is true, then this function only reorders self
     385             :    signatures (it still checks all signatures for duplicates,
     386             :    however).
     387             : 
     388             :    Returns 1 if the keyblock was modified, 0 otherwise.  */
     389             : static int
     390           2 : check_all_keysigs (KBNODE kb, int only_selected, int only_selfsigs)
     391             : {
     392             :   gpg_error_t err;
     393             :   PKT_public_key *pk;
     394             :   KBNODE n, n_next, *n_prevp, n2;
     395           2 :   char *pending_desc = NULL;
     396             :   PKT_public_key *issuer;
     397             :   KBNODE last_printed_component;
     398           2 :   KBNODE current_component = NULL;
     399           2 :   int dups = 0;
     400           2 :   int missing_issuer = 0;
     401           2 :   int reordered = 0;
     402           2 :   int bad_signature = 0;
     403           2 :   int missing_selfsig = 0;
     404           2 :   int modified = 0;
     405             : 
     406           2 :   log_assert (kb->pkt->pkttype == PKT_PUBLIC_KEY);
     407           2 :   pk = kb->pkt->pkt.public_key;
     408             : 
     409             :   /* First we look for duplicates.  */
     410             :   {
     411             :     int nsigs;
     412             :     kbnode_t *sigs;
     413             :     int i;
     414             :     int last_i;
     415             : 
     416             :     /* Count the sigs.  */
     417          14 :     for (nsigs = 0, n = kb; n; n = n->next)
     418             :       {
     419          12 :         if (is_deleted_kbnode (n))
     420           0 :           continue;
     421          12 :         else if (n->pkt->pkttype == PKT_SIGNATURE)
     422           5 :           nsigs ++;
     423             :       }
     424             : 
     425           2 :     if (!nsigs)
     426           0 :       return 0; /* No signatures at all.  */
     427             : 
     428             :     /* Add them all to the SIGS array.  */
     429           2 :     sigs = xtrycalloc (nsigs, sizeof *sigs);
     430           2 :     if (!sigs)
     431             :       {
     432           0 :         log_error (_("error allocating memory: %s\n"),
     433             :                    gpg_strerror (gpg_error_from_syserror ()));
     434           0 :         return 0;
     435             :       }
     436             : 
     437           2 :     i = 0;
     438          14 :     for (n = kb; n; n = n->next)
     439             :       {
     440          12 :         if (is_deleted_kbnode (n))
     441           0 :           continue;
     442             : 
     443          12 :         if (n->pkt->pkttype != PKT_SIGNATURE)
     444           7 :           continue;
     445             : 
     446           5 :         sigs[i] = n;
     447           5 :         i ++;
     448             :       }
     449           2 :     log_assert (i == nsigs);
     450             : 
     451           2 :     qsort (sigs, nsigs, sizeof (sigs[0]), sig_comparison);
     452             : 
     453           2 :     last_i = 0;
     454           5 :     for (i = 1; i < nsigs; i ++)
     455             :       {
     456           3 :         log_assert (sigs[last_i]);
     457           3 :         log_assert (sigs[last_i]->pkt->pkttype == PKT_SIGNATURE);
     458           3 :         log_assert (sigs[i]);
     459           3 :         log_assert (sigs[i]->pkt->pkttype == PKT_SIGNATURE);
     460             : 
     461           3 :         if (sig_comparison (&sigs[last_i], &sigs[i]) == 0)
     462             :           /* They are the same.  Kill the latter.  */
     463             :           {
     464           0 :             if (DBG_PACKET)
     465             :               {
     466           0 :                 PKT_signature *sig = sigs[i]->pkt->pkt.signature;
     467             : 
     468           0 :                 log_debug ("Signature appears multiple times, "
     469             :                            "deleting duplicate:\n");
     470           0 :                 log_debug ("  sig: class 0x%x, issuer: %s,"
     471             :                            " timestamp: %s (%lld), digest: %02x %02x\n",
     472           0 :                            sig->sig_class, keystr (sig->keyid),
     473             :                            isotimestamp (sig->timestamp),
     474           0 :                            (long long) sig->timestamp,
     475           0 :                            sig->digest_start[0], sig->digest_start[1]);
     476             :               }
     477             : 
     478             :             /* Remove sigs[i] from the keyblock.  */
     479             :             {
     480             :               KBNODE z, *prevp;
     481           0 :               int to_kill = last_i;
     482           0 :               last_i = i;
     483             : 
     484           0 :               for (prevp = &kb, z = kb; z; prevp = &z->next, z = z->next)
     485           0 :                 if (z == sigs[to_kill])
     486           0 :                   break;
     487             : 
     488           0 :               *prevp = sigs[to_kill]->next;
     489             : 
     490           0 :               sigs[to_kill]->next = NULL;
     491           0 :               release_kbnode (sigs[to_kill]);
     492           0 :               sigs[to_kill] = NULL;
     493             : 
     494           0 :               dups ++;
     495           0 :               modified = 1;
     496             :             }
     497             :           }
     498             :         else
     499           3 :           last_i = i;
     500             :       }
     501             : 
     502           2 :     xfree (sigs);
     503             :   }
     504             : 
     505             :   /* Make sure the sigs occur after the component (public key, subkey,
     506             :      user id) that they sign.  */
     507           2 :   issuer = NULL;
     508           2 :   last_printed_component = NULL;
     509          16 :   for (n_prevp = &kb, n = kb;
     510             :        n;
     511             :        /* If we moved n, then n_prevp is need valid.  */
     512          12 :        n_prevp = (n->next == n_next ? &n->next : n_prevp), n = n_next)
     513             :     {
     514             :       PACKET *p;
     515             :       int processed_current_component;
     516             :       PKT_signature *sig;
     517             :       int rc;
     518          12 :       int dump_sig_params = 0;
     519             : 
     520          12 :       n_next = n->next;
     521             : 
     522          12 :       if (is_deleted_kbnode (n))
     523           0 :         continue;
     524             : 
     525          12 :       p = n->pkt;
     526             : 
     527          12 :       if (issuer && issuer != pk)
     528             :         {
     529           0 :           free_public_key (issuer);
     530           0 :           issuer = NULL;
     531             :         }
     532             : 
     533          12 :       xfree (pending_desc);
     534          12 :       pending_desc = NULL;
     535             : 
     536          12 :       switch (p->pkttype)
     537             :         {
     538             :         case PKT_PUBLIC_KEY:
     539           2 :           log_assert (p->pkt.public_key == pk);
     540           2 :           if (only_selected && ! (n->flag & NODFLG_SELKEY))
     541             :             {
     542           0 :               current_component = NULL;
     543           0 :               break;
     544             :             }
     545             : 
     546           2 :           if (DBG_PACKET)
     547           0 :             log_debug ("public key %s: timestamp: %s (%lld)\n",
     548             :                        pk_keyid_str (pk),
     549             :                        isotimestamp (pk->timestamp),
     550           0 :                        (long long) pk->timestamp);
     551           2 :           current_component = n;
     552           2 :           break;
     553             :         case PKT_PUBLIC_SUBKEY:
     554           2 :           if (only_selected && ! (n->flag & NODFLG_SELKEY))
     555             :             {
     556           0 :               current_component = NULL;
     557           0 :               break;
     558             :             }
     559             : 
     560           2 :           if (DBG_PACKET)
     561           0 :             log_debug ("subkey %s: timestamp: %s (%lld)\n",
     562             :                        pk_keyid_str (p->pkt.public_key),
     563           0 :                        isotimestamp (p->pkt.public_key->timestamp),
     564           0 :                        (long long) p->pkt.public_key->timestamp);
     565           2 :           current_component = n;
     566           2 :           break;
     567             :         case PKT_USER_ID:
     568           3 :           if (only_selected && ! (n->flag & NODFLG_SELUID))
     569             :             {
     570           0 :               current_component = NULL;
     571           0 :               break;
     572             :             }
     573             : 
     574           3 :           if (DBG_PACKET)
     575           0 :             log_debug ("user id: %s\n",
     576           0 :                        p->pkt.user_id->attrib_data
     577             :                        ? "[ photo id ]"
     578           0 :                        : p->pkt.user_id->name);
     579           3 :           current_component = n;
     580           3 :           break;
     581             :         case PKT_SIGNATURE:
     582           5 :           if (! current_component)
     583             :             /* The current component is not selected, don't check the
     584             :                sigs under it.  */
     585           0 :             break;
     586             : 
     587           5 :           sig = n->pkt->pkt.signature;
     588             : 
     589          25 :           pending_desc = xasprintf ("  sig: class: 0x%x, issuer: %s,"
     590             :                                     " timestamp: %s (%lld), digest: %02x %02x",
     591           5 :                                     sig->sig_class,
     592           5 :                                     keystr (sig->keyid),
     593             :                                     isotimestamp (sig->timestamp),
     594           5 :                                     (long long) sig->timestamp,
     595          10 :                                     sig->digest_start[0], sig->digest_start[1]);
     596             : 
     597             : 
     598           5 :           if (keyid_cmp (pk_keyid (pk), sig->keyid) == 0)
     599           5 :             issuer = pk;
     600             :           else
     601             :             /* Issuer is a different key.  */
     602             :             {
     603           0 :               if (only_selfsigs)
     604           0 :                 continue;
     605             : 
     606           0 :               issuer = xmalloc (sizeof (*issuer));
     607           0 :               err = get_pubkey (issuer, sig->keyid);
     608           0 :               if (err)
     609             :                 {
     610           0 :                   xfree (issuer);
     611           0 :                   issuer = NULL;
     612           0 :                   if (DBG_PACKET)
     613             :                     {
     614           0 :                       if (pending_desc)
     615           0 :                         log_debug ("%s", pending_desc);
     616           0 :                       log_debug ("    Can't check signature allegedly"
     617             :                                  " issued by %s: %s\n",
     618           0 :                                  keystr (sig->keyid), gpg_strerror (err));
     619             :                     }
     620           0 :                   missing_issuer ++;
     621           0 :                   break;
     622             :                 }
     623             :             }
     624             : 
     625           5 :           if ((err = openpgp_pk_test_algo (sig->pubkey_algo)))
     626             :             {
     627           0 :               if (DBG_PACKET && pending_desc)
     628           0 :                 log_debug ("%s", pending_desc);
     629           0 :               tty_printf (_("can't check signature with unsupported"
     630             :                             " public-key algorithm (%d): %s.\n"),
     631           0 :                           sig->pubkey_algo, gpg_strerror (err));
     632           0 :               break;
     633             :             }
     634           5 :           if ((err = openpgp_md_test_algo (sig->digest_algo)))
     635             :             {
     636           0 :               if (DBG_PACKET && pending_desc)
     637           0 :                 log_debug ("%s", pending_desc);
     638           0 :               tty_printf (_("can't check signature with unsupported"
     639             :                             " message-digest algorithm %d: %s.\n"),
     640           0 :                           sig->digest_algo, gpg_strerror (err));
     641           0 :               break;
     642             :             }
     643             : 
     644             :           /* We iterate over the keyblock.  Most likely, the matching
     645             :              component is the current component so always try that
     646             :              first.  */
     647           5 :           processed_current_component = 0;
     648          10 :           for (n2 = current_component;
     649             :                n2;
     650           0 :                n2 = (processed_current_component ? n2->next : kb),
     651           0 :                  processed_current_component = 1)
     652           5 :             if (is_deleted_kbnode (n2))
     653           0 :               continue;
     654           5 :             else if (processed_current_component && n2 == current_component)
     655             :               /* Don't process it twice.  */
     656           0 :               continue;
     657             :             else
     658             :               {
     659           5 :                 err = check_signature_over_key_or_uid (issuer, sig, kb, n2->pkt,
     660             :                                                        NULL, NULL);
     661           5 :                 if (! err)
     662           5 :                   break;
     663             :               }
     664             : 
     665             :           /* n/sig is a signature and n2 is the component (public key,
     666             :              subkey or user id) that it signs, if any.
     667             :              current_component is that component that it appears to
     668             :              apply to (according to the ordering).  */
     669             : 
     670           5 :           if (current_component == n2)
     671             :             {
     672           5 :               if (DBG_PACKET)
     673             :                 {
     674           0 :                   log_debug ("%s", pending_desc);
     675           0 :                   log_debug ("    Good signature over last key or uid!\n");
     676             :                 }
     677             : 
     678           5 :               rc = 0;
     679             :             }
     680           0 :           else if (n2)
     681             :             {
     682           0 :               log_assert (n2->pkt->pkttype == PKT_USER_ID
     683             :                           || n2->pkt->pkttype == PKT_PUBLIC_KEY
     684             :                           || n2->pkt->pkttype == PKT_PUBLIC_SUBKEY);
     685             : 
     686           0 :               if (DBG_PACKET)
     687             :                 {
     688           0 :                   log_debug ("%s", pending_desc);
     689           0 :                   log_debug ("    Good signature out of order!"
     690             :                              "  (Over %s (%d) '%s')\n",
     691           0 :                              n2->pkt->pkttype == PKT_USER_ID
     692             :                              ? "user id"
     693           0 :                              : n2->pkt->pkttype == PKT_PUBLIC_SUBKEY
     694             :                              ? "subkey"
     695           0 :                              : "primary key",
     696           0 :                              n2->pkt->pkttype,
     697           0 :                              n2->pkt->pkttype == PKT_USER_ID
     698           0 :                              ? n2->pkt->pkt.user_id->name
     699           0 :                              : pk_keyid_str (n2->pkt->pkt.public_key));
     700             :                 }
     701             : 
     702             :               /* Reorder the packets: move the signature n to be just
     703             :                  after n2.  */
     704             : 
     705             :               /* Unlink the signature.  */
     706           0 :               log_assert (n_prevp);
     707           0 :               *n_prevp = n->next;
     708             : 
     709             :               /* Insert the sig immediately after the component.  */
     710           0 :               n->next = n2->next;
     711           0 :               n2->next = n;
     712             : 
     713           0 :               reordered ++;
     714           0 :               modified = 1;
     715             : 
     716           0 :               rc = 0;
     717             :             }
     718             :           else
     719             :             {
     720           0 :               if (DBG_PACKET)
     721             :                 {
     722           0 :                   log_debug ("%s", pending_desc);
     723           0 :                   log_debug ("    Bad signature.\n");
     724             :                 }
     725             : 
     726           0 :               if (DBG_PACKET)
     727           0 :                 dump_sig_params = 1;
     728             : 
     729           0 :               bad_signature ++;
     730             : 
     731           0 :               rc = GPG_ERR_BAD_SIGNATURE;
     732             :             }
     733             : 
     734             :           /* We don't cache the result here, because we haven't
     735             :              completely checked that the signature is legitimate.  For
     736             :              instance, if we have a revocation certificate on Alice's
     737             :              key signed by Bob, the signature may be good, but we
     738             :              haven't checked that Bob is a designated revoker.  */
     739             :           /* cache_sig_result (sig, rc); */
     740             : 
     741             :           {
     742           5 :             int has_selfsig = 0;
     743           5 :             if (! rc && issuer == pk)
     744             :               {
     745           5 :                 if (n2->pkt->pkttype == PKT_PUBLIC_KEY
     746           0 :                     && (/* Direct key signature.  */
     747           0 :                         sig->sig_class == 0x1f
     748             :                         /* Key revocation signature.  */
     749           0 :                         || sig->sig_class == 0x20))
     750           0 :                   has_selfsig = 1;
     751           5 :                 if (n2->pkt->pkttype == PKT_PUBLIC_SUBKEY
     752           2 :                     && (/* Subkey binding sig.  */
     753           2 :                         sig->sig_class == 0x18
     754             :                         /* Subkey revocation sig.  */
     755           0 :                         || sig->sig_class == 0x28))
     756           2 :                   has_selfsig = 1;
     757           5 :                 if (n2->pkt->pkttype == PKT_USER_ID
     758           3 :                     && (/* Certification sigs.  */
     759           3 :                         sig->sig_class == 0x10
     760           3 :                         || sig->sig_class == 0x11
     761           3 :                         || sig->sig_class == 0x12
     762           3 :                         || sig->sig_class == 0x13
     763             :                         /* Certification revocation sig.  */
     764           0 :                         || sig->sig_class == 0x30))
     765           3 :                   has_selfsig = 1;
     766             :               }
     767             : 
     768           5 :             if ((n2 && n2 != last_printed_component)
     769           0 :                 || (! n2 && last_printed_component != current_component))
     770             :               {
     771           5 :                 int is_reordered = n2 && n2 != current_component;
     772           5 :                 if (n2)
     773           5 :                   last_printed_component = n2;
     774             :                 else
     775           0 :                   last_printed_component = current_component;
     776             : 
     777           5 :                 if (!modified)
     778             :                   ;
     779           0 :                 else if (last_printed_component->pkt->pkttype == PKT_USER_ID)
     780             :                   {
     781           0 :                     tty_printf ("uid  ");
     782           0 :                     tty_print_utf8_string (last_printed_component
     783           0 :                                            ->pkt->pkt.user_id->name,
     784             :                                            last_printed_component
     785           0 :                                            ->pkt->pkt.user_id->len);
     786             :                   }
     787           0 :                 else if (last_printed_component->pkt->pkttype
     788             :                          == PKT_PUBLIC_KEY)
     789           0 :                   tty_printf ("pub  %s",
     790             :                               pk_keyid_str (last_printed_component
     791           0 :                                             ->pkt->pkt.public_key));
     792             :                 else
     793           0 :                   tty_printf ("sub  %s",
     794             :                               pk_keyid_str (last_printed_component
     795           0 :                                             ->pkt->pkt.public_key));
     796             : 
     797           5 :                 if (modified)
     798             :                   {
     799           0 :                     if (is_reordered)
     800           0 :                       tty_printf (_(" (reordered signatures follow)"));
     801           0 :                     tty_printf ("\n");
     802             :                   }
     803             :               }
     804             : 
     805           5 :             if (modified)
     806           0 :               print_one_sig (rc, kb, n, NULL, NULL, NULL, has_selfsig,
     807             :                              0, only_selfsigs);
     808             :           }
     809             : 
     810           5 :           if (dump_sig_params)
     811             :             {
     812             :               int i;
     813             : 
     814           0 :               for (i = 0; i < pubkey_get_nsig (sig->pubkey_algo); i ++)
     815             :                 {
     816             :                   char buffer[1024];
     817             :                   size_t len;
     818             :                   char *printable;
     819           0 :                   gcry_mpi_print (GCRYMPI_FMT_USG,
     820             :                                   buffer, sizeof (buffer), &len,
     821             :                                   sig->data[i]);
     822           0 :                   printable = bin2hex (buffer, len, NULL);
     823           0 :                   log_info ("        %d: %s\n", i, printable);
     824           0 :                   xfree (printable);
     825             :                 }
     826             :             }
     827           5 :           break;
     828             :         default:
     829           0 :           if (DBG_PACKET)
     830           0 :             log_debug ("unhandled packet: %d\n", p->pkttype);
     831           0 :           break;
     832             :         }
     833             :     }
     834             : 
     835           2 :   xfree (pending_desc);
     836           2 :   pending_desc = NULL;
     837             : 
     838           2 :   if (issuer != pk)
     839           0 :     free_public_key (issuer);
     840           2 :   issuer = NULL;
     841             : 
     842             :   /* Identify keys / uids that don't have a self-sig.  */
     843             :   {
     844           2 :     int has_selfsig = 0;
     845             :     PACKET *p;
     846             :     PKT_signature *sig;
     847             : 
     848           2 :     current_component = NULL;
     849          14 :     for (n = kb; n; n = n->next)
     850             :       {
     851          12 :         if (is_deleted_kbnode (n))
     852           0 :           continue;
     853             : 
     854          12 :         p = n->pkt;
     855             : 
     856          12 :         switch (p->pkttype)
     857             :           {
     858             :           case PKT_PUBLIC_KEY:
     859             :           case PKT_PUBLIC_SUBKEY:
     860             :           case PKT_USER_ID:
     861           7 :             if (current_component && ! has_selfsig)
     862           5 :               missing_selfsig ++;
     863           7 :             current_component = n;
     864           7 :             has_selfsig = 0;
     865           7 :             break;
     866             : 
     867             :           case PKT_SIGNATURE:
     868           5 :             if (! current_component || has_selfsig)
     869             :               break;
     870             : 
     871           5 :             sig = n->pkt->pkt.signature;
     872             : 
     873           5 :             if (! (sig->flags.checked && sig->flags.valid))
     874             :               break;
     875             : 
     876           0 :             if (keyid_cmp (pk_keyid (pk), sig->keyid) != 0)
     877             :               /* Different issuer, couldn't be a self-sig.  */
     878           0 :               break;
     879             : 
     880           0 :             if (current_component->pkt->pkttype == PKT_PUBLIC_KEY
     881           0 :                 && (/* Direct key signature.  */
     882           0 :                     sig->sig_class == 0x1f
     883             :                     /* Key revocation signature.  */
     884           0 :                     || sig->sig_class == 0x20))
     885           0 :               has_selfsig = 1;
     886           0 :             if (current_component->pkt->pkttype == PKT_PUBLIC_SUBKEY
     887           0 :                 && (/* Subkey binding sig.  */
     888           0 :                     sig->sig_class == 0x18
     889             :                     /* Subkey revocation sig.  */
     890           0 :                     || sig->sig_class == 0x28))
     891           0 :               has_selfsig = 1;
     892           0 :             if (current_component->pkt->pkttype == PKT_USER_ID
     893           0 :                 && (/* Certification sigs.  */
     894           0 :                     sig->sig_class == 0x10
     895           0 :                     || sig->sig_class == 0x11
     896           0 :                     || sig->sig_class == 0x12
     897           0 :                     || sig->sig_class == 0x13
     898             :                     /* Certification revocation sig.  */
     899           0 :                     || sig->sig_class == 0x30))
     900           0 :               has_selfsig = 1;
     901             : 
     902           0 :             break;
     903             : 
     904             :           default:
     905           0 :             if (current_component && ! has_selfsig)
     906           0 :               missing_selfsig ++;
     907           0 :             current_component = NULL;
     908             :           }
     909             :       }
     910             :   }
     911             : 
     912           2 :   if (dups || missing_issuer || bad_signature || reordered)
     913           0 :     tty_printf (_("key %s:\n"), pk_keyid_str (pk));
     914             : 
     915           2 :   if (dups)
     916           0 :     tty_printf (ngettext ("%d duplicate signature removed\n",
     917             :                           "%d duplicate signatures removed\n", dups), dups);
     918           2 :   if (missing_issuer)
     919           0 :     tty_printf (ngettext ("%d signature not checked due to a missing key\n",
     920             :                           "%d signatures not checked due to missing keys\n",
     921             :                           missing_issuer), missing_issuer);
     922           2 :   if (bad_signature)
     923           0 :     tty_printf (ngettext ("%d bad signature\n",
     924             :                           "%d bad signatures\n",
     925             :                           bad_signature), bad_signature);
     926           2 :   if (reordered)
     927           0 :     tty_printf (ngettext ("%d signature reordered\n",
     928             :                           "%d signatures reordered\n",
     929             :                           reordered), reordered);
     930             : 
     931           2 :   if (only_selfsigs && (bad_signature || reordered))
     932           0 :     tty_printf (_("Warning: errors found and only checked self-signatures,"
     933             :                   " run '%s' to check all signatures.\n"), "check");
     934             : 
     935           2 :   return modified;
     936             : }
     937             : 
     938             : 
     939             : static int
     940           1 : sign_mk_attrib (PKT_signature * sig, void *opaque)
     941             : {
     942           1 :   struct sign_attrib *attrib = opaque;
     943             :   byte buf[8];
     944             : 
     945           1 :   if (attrib->non_exportable)
     946             :     {
     947           0 :       buf[0] = 0;               /* not exportable */
     948           0 :       build_sig_subpkt (sig, SIGSUBPKT_EXPORTABLE, buf, 1);
     949             :     }
     950             : 
     951           1 :   if (attrib->non_revocable)
     952             :     {
     953           0 :       buf[0] = 0;               /* not revocable */
     954           0 :       build_sig_subpkt (sig, SIGSUBPKT_REVOCABLE, buf, 1);
     955             :     }
     956             : 
     957           1 :   if (attrib->reason)
     958           1 :     revocation_reason_build_cb (sig, attrib->reason);
     959             : 
     960           1 :   if (attrib->trust_depth)
     961             :     {
     962             :       /* Not critical.  If someone doesn't understand trust sigs,
     963             :          this can still be a valid regular signature. */
     964           0 :       buf[0] = attrib->trust_depth;
     965           0 :       buf[1] = attrib->trust_value;
     966           0 :       build_sig_subpkt (sig, SIGSUBPKT_TRUST, buf, 2);
     967             : 
     968             :       /* Critical.  If someone doesn't understands regexps, this
     969             :          whole sig should be invalid.  Note the +1 for the length -
     970             :          regexps are null terminated. */
     971           0 :       if (attrib->trust_regexp)
     972           0 :         build_sig_subpkt (sig, SIGSUBPKT_FLAG_CRITICAL | SIGSUBPKT_REGEXP,
     973           0 :                           attrib->trust_regexp,
     974           0 :                           strlen (attrib->trust_regexp) + 1);
     975             :     }
     976             : 
     977           1 :   return 0;
     978             : }
     979             : 
     980             : 
     981             : static void
     982           0 : trustsig_prompt (byte * trust_value, byte * trust_depth, char **regexp)
     983             : {
     984             :   char *p;
     985             : 
     986           0 :   *trust_value = 0;
     987           0 :   *trust_depth = 0;
     988           0 :   *regexp = NULL;
     989             : 
     990             :   /* Same string as pkclist.c:do_edit_ownertrust */
     991           0 :   tty_printf (_
     992             :               ("Please decide how far you trust this user to correctly verify"
     993             :                " other users' keys\n(by looking at passports, checking"
     994             :                " fingerprints from different sources, etc.)\n"));
     995           0 :   tty_printf ("\n");
     996           0 :   tty_printf (_("  %d = I trust marginally\n"), 1);
     997           0 :   tty_printf (_("  %d = I trust fully\n"), 2);
     998           0 :   tty_printf ("\n");
     999             : 
    1000           0 :   while (*trust_value == 0)
    1001             :     {
    1002           0 :       p = cpr_get ("trustsig_prompt.trust_value", _("Your selection? "));
    1003           0 :       trim_spaces (p);
    1004           0 :       cpr_kill_prompt ();
    1005             :       /* 60 and 120 are as per RFC2440 */
    1006           0 :       if (p[0] == '1' && !p[1])
    1007           0 :         *trust_value = 60;
    1008           0 :       else if (p[0] == '2' && !p[1])
    1009           0 :         *trust_value = 120;
    1010           0 :       xfree (p);
    1011             :     }
    1012             : 
    1013           0 :   tty_printf ("\n");
    1014             : 
    1015           0 :   tty_printf (_("Please enter the depth of this trust signature.\n"
    1016             :                 "A depth greater than 1 allows the key you are"
    1017             :                 " signing to make\n"
    1018             :                 "trust signatures on your behalf.\n"));
    1019           0 :   tty_printf ("\n");
    1020             : 
    1021           0 :   while (*trust_depth == 0)
    1022             :     {
    1023           0 :       p = cpr_get ("trustsig_prompt.trust_depth", _("Your selection? "));
    1024           0 :       trim_spaces (p);
    1025           0 :       cpr_kill_prompt ();
    1026           0 :       *trust_depth = atoi (p);
    1027           0 :       xfree (p);
    1028             :     }
    1029             : 
    1030           0 :   tty_printf ("\n");
    1031             : 
    1032           0 :   tty_printf (_("Please enter a domain to restrict this signature, "
    1033             :                 "or enter for none.\n"));
    1034             : 
    1035           0 :   tty_printf ("\n");
    1036             : 
    1037           0 :   p = cpr_get ("trustsig_prompt.trust_regexp", _("Your selection? "));
    1038           0 :   trim_spaces (p);
    1039           0 :   cpr_kill_prompt ();
    1040             : 
    1041           0 :   if (strlen (p) > 0)
    1042             :     {
    1043           0 :       char *q = p;
    1044           0 :       int regexplen = 100, ind;
    1045             : 
    1046           0 :       *regexp = xmalloc (regexplen);
    1047             : 
    1048             :       /* Now mangle the domain the user entered into a regexp.  To do
    1049             :          this, \-escape everything that isn't alphanumeric, and attach
    1050             :          "<[^>]+[@.]" to the front, and ">$" to the end. */
    1051             : 
    1052           0 :       strcpy (*regexp, "<[^>]+[@.]");
    1053           0 :       ind = strlen (*regexp);
    1054             : 
    1055           0 :       while (*q)
    1056             :         {
    1057           0 :           if (!((*q >= 'A' && *q <= 'Z')
    1058           0 :                 || (*q >= 'a' && *q <= 'z') || (*q >= '0' && *q <= '9')))
    1059           0 :             (*regexp)[ind++] = '\\';
    1060             : 
    1061           0 :           (*regexp)[ind++] = *q;
    1062             : 
    1063           0 :           if ((regexplen - ind) < 3)
    1064             :             {
    1065           0 :               regexplen += 100;
    1066           0 :               *regexp = xrealloc (*regexp, regexplen);
    1067             :             }
    1068             : 
    1069           0 :           q++;
    1070             :         }
    1071             : 
    1072           0 :       (*regexp)[ind] = '\0';
    1073           0 :       strcat (*regexp, ">$");
    1074             :     }
    1075             : 
    1076           0 :   xfree (p);
    1077           0 :   tty_printf ("\n");
    1078           0 : }
    1079             : 
    1080             : 
    1081             : /*
    1082             :  * Loop over all LOCUSR and and sign the uids after asking.  If no
    1083             :  * user id is marked, all user ids will be signed; if some user_ids
    1084             :  * are marked only those will be signed.  If QUICK is true the
    1085             :  * function won't ask the user and use sensible defaults.
    1086             :  */
    1087             : static int
    1088           0 : sign_uids (ctrl_t ctrl, estream_t fp,
    1089             :            kbnode_t keyblock, strlist_t locusr, int *ret_modified,
    1090             :            int local, int nonrevocable, int trust, int interactive,
    1091             :            int quick)
    1092             : {
    1093           0 :   int rc = 0;
    1094           0 :   SK_LIST sk_list = NULL;
    1095           0 :   SK_LIST sk_rover = NULL;
    1096           0 :   PKT_public_key *pk = NULL;
    1097             :   KBNODE node, uidnode;
    1098           0 :   PKT_public_key *primary_pk = NULL;
    1099           0 :   int select_all = !count_selected_uids (keyblock) || interactive;
    1100             : 
    1101             :   /* Build a list of all signators.
    1102             :    *
    1103             :    * We use the CERT flag to request the primary which must always
    1104             :    * be one which is capable of signing keys.  I can't see a reason
    1105             :    * why to sign keys using a subkey.  Implementation of USAGE_CERT
    1106             :    * is just a hack in getkey.c and does not mean that a subkey
    1107             :    * marked as certification capable will be used. */
    1108           0 :   rc = build_sk_list (ctrl, locusr, &sk_list, PUBKEY_USAGE_CERT);
    1109           0 :   if (rc)
    1110           0 :     goto leave;
    1111             : 
    1112             :   /* Loop over all signators.  */
    1113           0 :   for (sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next)
    1114             :     {
    1115             :       u32 sk_keyid[2], pk_keyid[2];
    1116           0 :       char *p, *trust_regexp = NULL;
    1117           0 :       int class = 0, selfsig = 0;
    1118           0 :       u32 duration = 0, timestamp = 0;
    1119           0 :       byte trust_depth = 0, trust_value = 0;
    1120             : 
    1121           0 :       pk = sk_rover->pk;
    1122           0 :       keyid_from_pk (pk, sk_keyid);
    1123             : 
    1124             :       /* Set mark A for all selected user ids.  */
    1125           0 :       for (node = keyblock; node; node = node->next)
    1126             :         {
    1127           0 :           if (select_all || (node->flag & NODFLG_SELUID))
    1128           0 :             node->flag |= NODFLG_MARK_A;
    1129             :           else
    1130           0 :             node->flag &= ~NODFLG_MARK_A;
    1131             :         }
    1132             : 
    1133             :       /* Reset mark for uids which are already signed.  */
    1134           0 :       uidnode = NULL;
    1135           0 :       for (node = keyblock; node; node = node->next)
    1136             :         {
    1137           0 :           if (node->pkt->pkttype == PKT_PUBLIC_KEY)
    1138             :             {
    1139           0 :               primary_pk = node->pkt->pkt.public_key;
    1140           0 :               keyid_from_pk (primary_pk, pk_keyid);
    1141             : 
    1142             :               /* Is this a self-sig? */
    1143           0 :               if (pk_keyid[0] == sk_keyid[0] && pk_keyid[1] == sk_keyid[1])
    1144           0 :                 selfsig = 1;
    1145             :             }
    1146           0 :           else if (node->pkt->pkttype == PKT_USER_ID)
    1147             :             {
    1148           0 :               uidnode = (node->flag & NODFLG_MARK_A) ? node : NULL;
    1149           0 :               if (uidnode)
    1150             :                 {
    1151           0 :                   int yesreally = 0;
    1152             :                   char *user;
    1153             : 
    1154           0 :                   user = utf8_to_native (uidnode->pkt->pkt.user_id->name,
    1155           0 :                                          uidnode->pkt->pkt.user_id->len, 0);
    1156             : 
    1157           0 :                   if (opt.only_sign_text_ids
    1158           0 :                       && uidnode->pkt->pkt.user_id->attribs)
    1159             :                     {
    1160           0 :                       tty_fprintf (fp, _("Skipping user ID \"%s\","
    1161             :                                          " which is not a text ID.\n"),
    1162             :                                    user);
    1163           0 :                       uidnode->flag &= ~NODFLG_MARK_A;
    1164           0 :                       uidnode = NULL;
    1165             :                     }
    1166           0 :                   else if (uidnode->pkt->pkt.user_id->is_revoked)
    1167             :                     {
    1168           0 :                       tty_fprintf (fp, _("User ID \"%s\" is revoked."), user);
    1169             : 
    1170           0 :                       if (selfsig)
    1171           0 :                         tty_fprintf (fp, "\n");
    1172           0 :                       else if (opt.expert && !quick)
    1173             :                         {
    1174           0 :                           tty_fprintf (fp, "\n");
    1175             :                           /* No, so remove the mark and continue */
    1176           0 :                           if (!cpr_get_answer_is_yes ("sign_uid.revoke_okay",
    1177           0 :                                                       _("Are you sure you "
    1178             :                                                         "still want to sign "
    1179             :                                                         "it? (y/N) ")))
    1180             :                             {
    1181           0 :                               uidnode->flag &= ~NODFLG_MARK_A;
    1182           0 :                               uidnode = NULL;
    1183             :                             }
    1184           0 :                           else if (interactive)
    1185           0 :                             yesreally = 1;
    1186             :                         }
    1187             :                       else
    1188             :                         {
    1189           0 :                           uidnode->flag &= ~NODFLG_MARK_A;
    1190           0 :                           uidnode = NULL;
    1191           0 :                           tty_fprintf (fp, _("  Unable to sign.\n"));
    1192             :                         }
    1193             :                     }
    1194           0 :                   else if (uidnode->pkt->pkt.user_id->is_expired)
    1195             :                     {
    1196           0 :                       tty_fprintf (fp, _("User ID \"%s\" is expired."), user);
    1197             : 
    1198           0 :                       if (selfsig)
    1199           0 :                         tty_fprintf (fp, "\n");
    1200           0 :                       else if (opt.expert && !quick)
    1201             :                         {
    1202           0 :                           tty_fprintf (fp, "\n");
    1203             :                           /* No, so remove the mark and continue */
    1204           0 :                           if (!cpr_get_answer_is_yes ("sign_uid.expire_okay",
    1205           0 :                                                       _("Are you sure you "
    1206             :                                                         "still want to sign "
    1207             :                                                         "it? (y/N) ")))
    1208             :                             {
    1209           0 :                               uidnode->flag &= ~NODFLG_MARK_A;
    1210           0 :                               uidnode = NULL;
    1211             :                             }
    1212           0 :                           else if (interactive)
    1213           0 :                             yesreally = 1;
    1214             :                         }
    1215             :                       else
    1216             :                         {
    1217           0 :                           uidnode->flag &= ~NODFLG_MARK_A;
    1218           0 :                           uidnode = NULL;
    1219           0 :                           tty_fprintf (fp, _("  Unable to sign.\n"));
    1220             :                         }
    1221             :                     }
    1222           0 :                   else if (!uidnode->pkt->pkt.user_id->created && !selfsig)
    1223             :                     {
    1224           0 :                       tty_fprintf (fp, _("User ID \"%s\" is not self-signed."),
    1225             :                                    user);
    1226             : 
    1227           0 :                       if (opt.expert && !quick)
    1228             :                         {
    1229           0 :                           tty_fprintf (fp, "\n");
    1230             :                           /* No, so remove the mark and continue */
    1231           0 :                           if (!cpr_get_answer_is_yes ("sign_uid.nosig_okay",
    1232           0 :                                                       _("Are you sure you "
    1233             :                                                         "still want to sign "
    1234             :                                                         "it? (y/N) ")))
    1235             :                             {
    1236           0 :                               uidnode->flag &= ~NODFLG_MARK_A;
    1237           0 :                               uidnode = NULL;
    1238             :                             }
    1239           0 :                           else if (interactive)
    1240           0 :                             yesreally = 1;
    1241             :                         }
    1242             :                       else
    1243             :                         {
    1244           0 :                           uidnode->flag &= ~NODFLG_MARK_A;
    1245           0 :                           uidnode = NULL;
    1246           0 :                           tty_fprintf (fp, _("  Unable to sign.\n"));
    1247             :                         }
    1248             :                     }
    1249             : 
    1250           0 :                   if (uidnode && interactive && !yesreally && !quick)
    1251             :                     {
    1252           0 :                       tty_fprintf (fp,
    1253           0 :                                    _("User ID \"%s\" is signable.  "), user);
    1254           0 :                       if (!cpr_get_answer_is_yes ("sign_uid.sign_okay",
    1255           0 :                                                   _("Sign it? (y/N) ")))
    1256             :                         {
    1257           0 :                           uidnode->flag &= ~NODFLG_MARK_A;
    1258           0 :                           uidnode = NULL;
    1259             :                         }
    1260             :                     }
    1261             : 
    1262           0 :                   xfree (user);
    1263             :                 }
    1264             :             }
    1265           0 :           else if (uidnode && node->pkt->pkttype == PKT_SIGNATURE
    1266           0 :                    && (node->pkt->pkt.signature->sig_class & ~3) == 0x10)
    1267             :             {
    1268           0 :               if (sk_keyid[0] == node->pkt->pkt.signature->keyid[0]
    1269           0 :                   && sk_keyid[1] == node->pkt->pkt.signature->keyid[1])
    1270             :                 {
    1271             :                   char buf[50];
    1272             :                   char *user;
    1273             : 
    1274           0 :                   user = utf8_to_native (uidnode->pkt->pkt.user_id->name,
    1275           0 :                                          uidnode->pkt->pkt.user_id->len, 0);
    1276             : 
    1277             :                   /* It's a v3 self-sig.  Make it into a v4 self-sig? */
    1278           0 :                   if (node->pkt->pkt.signature->version < 4
    1279           0 :                       && selfsig && !quick)
    1280             :                     {
    1281           0 :                       tty_fprintf (fp,
    1282           0 :                                    _("The self-signature on \"%s\"\n"
    1283             :                                      "is a PGP 2.x-style signature.\n"), user);
    1284             : 
    1285             :                       /* Note that the regular PGP2 warning below
    1286             :                          still applies if there are no v4 sigs on
    1287             :                          this key at all. */
    1288             : 
    1289           0 :                       if (opt.expert)
    1290           0 :                         if (cpr_get_answer_is_yes ("sign_uid.v4_promote_okay",
    1291           0 :                                                    _("Do you want to promote "
    1292             :                                                      "it to an OpenPGP self-"
    1293             :                                                      "signature? (y/N) ")))
    1294             :                           {
    1295           0 :                             node->flag |= NODFLG_DELSIG;
    1296           0 :                             xfree (user);
    1297           0 :                             continue;
    1298             :                           }
    1299             :                     }
    1300             : 
    1301             :                   /* Is the current signature expired? */
    1302           0 :                   if (node->pkt->pkt.signature->flags.expired)
    1303             :                     {
    1304           0 :                       tty_fprintf (fp, _("Your current signature on \"%s\"\n"
    1305             :                                          "has expired.\n"), user);
    1306             : 
    1307           0 :                       if (quick || cpr_get_answer_is_yes
    1308             :                           ("sign_uid.replace_expired_okay",
    1309           0 :                            _("Do you want to issue a "
    1310             :                              "new signature to replace "
    1311             :                              "the expired one? (y/N) ")))
    1312             :                         {
    1313             :                           /* Mark these for later deletion.  We
    1314             :                              don't want to delete them here, just in
    1315             :                              case the replacement signature doesn't
    1316             :                              happen for some reason.  We only delete
    1317             :                              these after the replacement is already
    1318             :                              in place. */
    1319             : 
    1320           0 :                           node->flag |= NODFLG_DELSIG;
    1321           0 :                           xfree (user);
    1322           0 :                           continue;
    1323             :                         }
    1324             :                     }
    1325             : 
    1326           0 :                   if (!node->pkt->pkt.signature->flags.exportable && !local)
    1327             :                     {
    1328             :                       /* It's a local sig, and we want to make a
    1329             :                          exportable sig. */
    1330           0 :                       tty_fprintf (fp, _("Your current signature on \"%s\"\n"
    1331             :                                          "is a local signature.\n"), user);
    1332             : 
    1333           0 :                       if (quick || cpr_get_answer_is_yes
    1334             :                           ("sign_uid.local_promote_okay",
    1335           0 :                            _("Do you want to promote "
    1336             :                              "it to a full exportable " "signature? (y/N) ")))
    1337             :                         {
    1338             :                           /* Mark these for later deletion.  We
    1339             :                              don't want to delete them here, just in
    1340             :                              case the replacement signature doesn't
    1341             :                              happen for some reason.  We only delete
    1342             :                              these after the replacement is already
    1343             :                              in place. */
    1344             : 
    1345           0 :                           node->flag |= NODFLG_DELSIG;
    1346           0 :                           xfree (user);
    1347           0 :                           continue;
    1348             :                         }
    1349             :                     }
    1350             : 
    1351             :                   /* Fixme: see whether there is a revocation in which
    1352             :                    * case we should allow signing it again. */
    1353           0 :                   if (!node->pkt->pkt.signature->flags.exportable && local)
    1354           0 :                     tty_fprintf ( fp,
    1355           0 :                        _("\"%s\" was already locally signed by key %s\n"),
    1356             :                        user, keystr_from_pk (pk));
    1357             :                   else
    1358           0 :                     tty_fprintf (fp,
    1359           0 :                                 _("\"%s\" was already signed by key %s\n"),
    1360             :                                 user, keystr_from_pk (pk));
    1361             : 
    1362           0 :                   if (opt.expert && !quick
    1363           0 :                       && cpr_get_answer_is_yes ("sign_uid.dupe_okay",
    1364           0 :                                                 _("Do you want to sign it "
    1365             :                                                   "again anyway? (y/N) ")))
    1366             :                     {
    1367             :                       /* Don't delete the old sig here since this is
    1368             :                          an --expert thing. */
    1369           0 :                       xfree (user);
    1370           0 :                       continue;
    1371             :                     }
    1372             : 
    1373           0 :                   snprintf (buf, sizeof buf, "%08lX%08lX",
    1374           0 :                             (ulong) pk->keyid[0], (ulong) pk->keyid[1]);
    1375           0 :                   write_status_text (STATUS_ALREADY_SIGNED, buf);
    1376           0 :                   uidnode->flag &= ~NODFLG_MARK_A;       /* remove mark */
    1377             : 
    1378           0 :                   xfree (user);
    1379             :                 }
    1380             :             }
    1381             :         }
    1382             : 
    1383             :       /* Check whether any uids are left for signing.  */
    1384           0 :       if (!count_uids_with_flag (keyblock, NODFLG_MARK_A))
    1385             :         {
    1386           0 :           tty_fprintf (fp, _("Nothing to sign with key %s\n"),
    1387             :                       keystr_from_pk (pk));
    1388           0 :           continue;
    1389             :         }
    1390             : 
    1391             :       /* Ask whether we really should sign these user id(s). */
    1392           0 :       tty_fprintf (fp, "\n");
    1393           0 :       show_key_with_all_names (ctrl, fp, keyblock, 1, 0, 1, 0, 0, 0);
    1394           0 :       tty_fprintf (fp, "\n");
    1395             : 
    1396           0 :       if (primary_pk->expiredate && !selfsig)
    1397             :         {
    1398             :           /* Static analyzer note: A claim that PRIMARY_PK might be
    1399             :              NULL is not correct because it set from the public key
    1400             :              packet which is always the first packet in a keyblock and
    1401             :              parsed in the above loop over the keyblock.  In case the
    1402             :              keyblock has no packets at all and thus the loop was not
    1403             :              entered the above count_uids_with_flag would have
    1404             :              detected this case.  */
    1405             : 
    1406           0 :           u32 now = make_timestamp ();
    1407             : 
    1408           0 :           if (primary_pk->expiredate <= now)
    1409             :             {
    1410           0 :               tty_fprintf (fp, _("This key has expired!"));
    1411             : 
    1412           0 :               if (opt.expert && !quick)
    1413             :                 {
    1414           0 :                   tty_fprintf (fp, "  ");
    1415           0 :                   if (!cpr_get_answer_is_yes ("sign_uid.expired_okay",
    1416           0 :                                               _("Are you sure you still "
    1417             :                                                 "want to sign it? (y/N) ")))
    1418           0 :                     continue;
    1419             :                 }
    1420             :               else
    1421             :                 {
    1422           0 :                   tty_fprintf (fp, _("  Unable to sign.\n"));
    1423           0 :                   continue;
    1424             :                 }
    1425             :             }
    1426             :           else
    1427             :             {
    1428           0 :               tty_fprintf (fp, _("This key is due to expire on %s.\n"),
    1429             :                            expirestr_from_pk (primary_pk));
    1430             : 
    1431           0 :               if (opt.ask_cert_expire && !quick)
    1432             :                 {
    1433           0 :                   char *answer = cpr_get ("sign_uid.expire",
    1434           0 :                                           _("Do you want your signature to "
    1435             :                                             "expire at the same time? (Y/n) "));
    1436           0 :                   if (answer_is_yes_no_default (answer, 1))
    1437             :                     {
    1438             :                       /* This fixes the signature timestamp we're
    1439             :                          going to make as now.  This is so the
    1440             :                          expiration date is exactly correct, and not
    1441             :                          a few seconds off (due to the time it takes
    1442             :                          to answer the questions, enter the
    1443             :                          passphrase, etc). */
    1444           0 :                       timestamp = now;
    1445           0 :                       duration = primary_pk->expiredate - now;
    1446             :                     }
    1447             : 
    1448           0 :                   cpr_kill_prompt ();
    1449           0 :                   xfree (answer);
    1450             :                 }
    1451             :             }
    1452             :         }
    1453             : 
    1454             :       /* Only ask for duration if we haven't already set it to match
    1455             :          the expiration of the pk */
    1456           0 :       if (!duration && !selfsig)
    1457             :         {
    1458           0 :           if (opt.ask_cert_expire && !quick)
    1459           0 :             duration = ask_expire_interval (1, opt.def_cert_expire);
    1460             :           else
    1461           0 :             duration = parse_expire_string (opt.def_cert_expire);
    1462             :         }
    1463             : 
    1464           0 :       if (selfsig)
    1465             :         ;
    1466             :       else
    1467             :         {
    1468           0 :           if (opt.batch || !opt.ask_cert_level || quick)
    1469           0 :             class = 0x10 + opt.def_cert_level;
    1470             :           else
    1471             :             {
    1472             :               char *answer;
    1473             : 
    1474           0 :               tty_fprintf (fp,
    1475           0 :                            _("How carefully have you verified the key you are "
    1476             :                             "about to sign actually belongs\nto the person "
    1477             :                             "named above?  If you don't know what to "
    1478             :                             "answer, enter \"0\".\n"));
    1479           0 :               tty_fprintf (fp, "\n");
    1480           0 :               tty_fprintf (fp, _("   (0) I will not answer.%s\n"),
    1481           0 :                           opt.def_cert_level == 0 ? " (default)" : "");
    1482           0 :               tty_fprintf (fp, _("   (1) I have not checked at all.%s\n"),
    1483           0 :                           opt.def_cert_level == 1 ? " (default)" : "");
    1484           0 :               tty_fprintf (fp, _("   (2) I have done casual checking.%s\n"),
    1485           0 :                           opt.def_cert_level == 2 ? " (default)" : "");
    1486           0 :               tty_fprintf (fp,
    1487           0 :                            _("   (3) I have done very careful checking.%s\n"),
    1488           0 :                           opt.def_cert_level == 3 ? " (default)" : "");
    1489           0 :               tty_fprintf (fp, "\n");
    1490             : 
    1491           0 :               while (class == 0)
    1492             :                 {
    1493           0 :                   answer = cpr_get ("sign_uid.class",
    1494           0 :                                     _("Your selection? "
    1495             :                                       "(enter '?' for more information): "));
    1496           0 :                   if (answer[0] == '\0')
    1497           0 :                     class = 0x10 + opt.def_cert_level;  /* Default */
    1498           0 :                   else if (ascii_strcasecmp (answer, "0") == 0)
    1499           0 :                     class = 0x10;       /* Generic */
    1500           0 :                   else if (ascii_strcasecmp (answer, "1") == 0)
    1501           0 :                     class = 0x11;       /* Persona */
    1502           0 :                   else if (ascii_strcasecmp (answer, "2") == 0)
    1503           0 :                     class = 0x12;       /* Casual */
    1504           0 :                   else if (ascii_strcasecmp (answer, "3") == 0)
    1505           0 :                     class = 0x13;       /* Positive */
    1506             :                   else
    1507           0 :                     tty_fprintf (fp, _("Invalid selection.\n"));
    1508             : 
    1509           0 :                   xfree (answer);
    1510             :                 }
    1511             :             }
    1512             : 
    1513           0 :           if (trust && !quick)
    1514           0 :             trustsig_prompt (&trust_value, &trust_depth, &trust_regexp);
    1515             :         }
    1516             : 
    1517           0 :       if (!quick)
    1518             :         {
    1519           0 :           p = get_user_id_native (sk_keyid);
    1520           0 :           tty_fprintf (fp,
    1521           0 :                    _("Are you sure that you want to sign this key with your\n"
    1522             :                      "key \"%s\" (%s)\n"), p, keystr_from_pk (pk));
    1523           0 :           xfree (p);
    1524             :         }
    1525             : 
    1526           0 :       if (selfsig)
    1527             :         {
    1528           0 :           tty_fprintf (fp, "\n");
    1529           0 :           tty_fprintf (fp, _("This will be a self-signature.\n"));
    1530             : 
    1531           0 :           if (local)
    1532             :             {
    1533           0 :               tty_fprintf (fp, "\n");
    1534           0 :               tty_fprintf (fp, _("WARNING: the signature will not be marked "
    1535             :                                  "as non-exportable.\n"));
    1536             :             }
    1537             : 
    1538           0 :           if (nonrevocable)
    1539             :             {
    1540           0 :               tty_fprintf (fp, "\n");
    1541           0 :               tty_fprintf (fp, _("WARNING: the signature will not be marked "
    1542             :                                  "as non-revocable.\n"));
    1543             :             }
    1544             :         }
    1545             :       else
    1546             :         {
    1547           0 :           if (local)
    1548             :             {
    1549           0 :               tty_fprintf (fp, "\n");
    1550           0 :               tty_fprintf (fp,
    1551           0 :                  _("The signature will be marked as non-exportable.\n"));
    1552             :             }
    1553             : 
    1554           0 :           if (nonrevocable)
    1555             :             {
    1556           0 :               tty_fprintf (fp, "\n");
    1557           0 :               tty_fprintf (fp,
    1558           0 :                  _("The signature will be marked as non-revocable.\n"));
    1559             :             }
    1560             : 
    1561           0 :           switch (class)
    1562             :             {
    1563             :             case 0x11:
    1564           0 :               tty_fprintf (fp, "\n");
    1565           0 :               tty_fprintf (fp, _("I have not checked this key at all.\n"));
    1566           0 :               break;
    1567             : 
    1568             :             case 0x12:
    1569           0 :               tty_fprintf (fp, "\n");
    1570           0 :               tty_fprintf (fp, _("I have checked this key casually.\n"));
    1571           0 :               break;
    1572             : 
    1573             :             case 0x13:
    1574           0 :               tty_fprintf (fp, "\n");
    1575           0 :               tty_fprintf (fp, _("I have checked this key very carefully.\n"));
    1576           0 :               break;
    1577             :             }
    1578             :         }
    1579             : 
    1580           0 :       tty_fprintf (fp, "\n");
    1581             : 
    1582           0 :       if (opt.batch && opt.answer_yes)
    1583             :         ;
    1584           0 :       else if (quick)
    1585             :         ;
    1586           0 :       else if (!cpr_get_answer_is_yes ("sign_uid.okay",
    1587           0 :                                        _("Really sign? (y/N) ")))
    1588           0 :         continue;
    1589             : 
    1590             :       /* Now we can sign the user ids.  */
    1591             :     reloop:  /* (Must use this, because we are modifing the list.)  */
    1592           0 :       primary_pk = NULL;
    1593           0 :       for (node = keyblock; node; node = node->next)
    1594             :         {
    1595           0 :           if (node->pkt->pkttype == PKT_PUBLIC_KEY)
    1596           0 :             primary_pk = node->pkt->pkt.public_key;
    1597           0 :           else if (node->pkt->pkttype == PKT_USER_ID
    1598           0 :                    && (node->flag & NODFLG_MARK_A))
    1599             :             {
    1600             :               PACKET *pkt;
    1601             :               PKT_signature *sig;
    1602             :               struct sign_attrib attrib;
    1603             : 
    1604           0 :               log_assert (primary_pk);
    1605           0 :               memset (&attrib, 0, sizeof attrib);
    1606           0 :               attrib.non_exportable = local;
    1607           0 :               attrib.non_revocable = nonrevocable;
    1608           0 :               attrib.trust_depth = trust_depth;
    1609           0 :               attrib.trust_value = trust_value;
    1610           0 :               attrib.trust_regexp = trust_regexp;
    1611           0 :               node->flag &= ~NODFLG_MARK_A;
    1612             : 
    1613             :               /* We force creation of a v4 signature for local
    1614             :                * signatures, otherwise we would not generate the
    1615             :                * subpacket with v3 keys and the signature becomes
    1616             :                * exportable.  */
    1617             : 
    1618           0 :               if (selfsig)
    1619           0 :                 rc = make_keysig_packet (&sig, primary_pk,
    1620           0 :                                          node->pkt->pkt.user_id,
    1621             :                                          NULL,
    1622             :                                          pk,
    1623             :                                          0x13, 0, 0, 0,
    1624             :                                          keygen_add_std_prefs, primary_pk,
    1625             :                                          NULL);
    1626             :               else
    1627           0 :                 rc = make_keysig_packet (&sig, primary_pk,
    1628           0 :                                          node->pkt->pkt.user_id,
    1629             :                                          NULL,
    1630             :                                          pk,
    1631             :                                          class, 0,
    1632             :                                          timestamp, duration,
    1633             :                                          sign_mk_attrib, &attrib,
    1634             :                                          NULL);
    1635           0 :               if (rc)
    1636             :                 {
    1637           0 :                   write_status_error ("keysig", rc);
    1638           0 :                   log_error (_("signing failed: %s\n"), gpg_strerror (rc));
    1639           0 :                   goto leave;
    1640             :                 }
    1641             : 
    1642           0 :               *ret_modified = 1;        /* We changed the keyblock. */
    1643           0 :               update_trust = 1;
    1644             : 
    1645           0 :               pkt = xmalloc_clear (sizeof *pkt);
    1646           0 :               pkt->pkttype = PKT_SIGNATURE;
    1647           0 :               pkt->pkt.signature = sig;
    1648           0 :               insert_kbnode (node, new_kbnode (pkt), PKT_SIGNATURE);
    1649           0 :               goto reloop;
    1650             :             }
    1651             :         }
    1652             : 
    1653             :       /* Delete any sigs that got promoted */
    1654           0 :       for (node = keyblock; node; node = node->next)
    1655           0 :         if (node->flag & NODFLG_DELSIG)
    1656           0 :           delete_kbnode (node);
    1657             :     } /* End loop over signators.  */
    1658             : 
    1659             :  leave:
    1660           0 :   release_sk_list (sk_list);
    1661           0 :   return rc;
    1662             : }
    1663             : 
    1664             : 
    1665             : /*
    1666             :  * Change the passphrase of the primary and all secondary keys.  Note
    1667             :  * that it is common to use only one passphrase for the primary and
    1668             :  * all subkeys.  However, this is now (since GnuPG 2.1) all up to the
    1669             :  * gpg-agent.  Returns 0 on success or an error code.
    1670             :  */
    1671             : static gpg_error_t
    1672           0 : change_passphrase (ctrl_t ctrl, kbnode_t keyblock)
    1673             : {
    1674             :   gpg_error_t err;
    1675             :   kbnode_t node;
    1676             :   PKT_public_key *pk;
    1677             :   int any;
    1678             :   u32 keyid[2], subid[2];
    1679           0 :   char *hexgrip = NULL;
    1680           0 :   char *cache_nonce = NULL;
    1681           0 :   char *passwd_nonce = NULL;
    1682             : 
    1683           0 :   node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
    1684           0 :   if (!node)
    1685             :     {
    1686           0 :       log_error ("Oops; public key missing!\n");
    1687           0 :       err = gpg_error (GPG_ERR_INTERNAL);
    1688           0 :       goto leave;
    1689             :     }
    1690           0 :   pk = node->pkt->pkt.public_key;
    1691           0 :   keyid_from_pk (pk, keyid);
    1692             : 
    1693             :   /* Check whether it is likely that we will be able to change the
    1694             :      passphrase for any subkey.  */
    1695           0 :   for (any = 0, node = keyblock; node; node = node->next)
    1696             :     {
    1697           0 :       if (node->pkt->pkttype == PKT_PUBLIC_KEY
    1698           0 :           || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
    1699             :         {
    1700             :           char *serialno;
    1701             : 
    1702           0 :           pk = node->pkt->pkt.public_key;
    1703           0 :           keyid_from_pk (pk, subid);
    1704             : 
    1705           0 :           xfree (hexgrip);
    1706           0 :           err = hexkeygrip_from_pk (pk, &hexgrip);
    1707           0 :           if (err)
    1708           0 :             goto leave;
    1709           0 :           err = agent_get_keyinfo (ctrl, hexgrip, &serialno, NULL);
    1710           0 :           if (!err && serialno)
    1711             :             ; /* Key on card.  */
    1712           0 :           else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
    1713             :             ; /* Maybe stub key. */
    1714           0 :           else if (!err)
    1715           0 :             any = 1; /* Key is known.  */
    1716             :           else
    1717           0 :             log_error ("key %s: error getting keyinfo from agent: %s\n",
    1718             :                        keystr_with_sub (keyid, subid), gpg_strerror (err));
    1719           0 :           xfree (serialno);
    1720             :         }
    1721             :     }
    1722           0 :   err = 0;
    1723           0 :   if (!any)
    1724             :     {
    1725           0 :       tty_printf (_("Key has only stub or on-card key items - "
    1726             :                     "no passphrase to change.\n"));
    1727           0 :       goto leave;
    1728             :     }
    1729             : 
    1730             :   /* Change the passphrase for all keys.  */
    1731           0 :   for (node = keyblock; node; node = node->next)
    1732             :     {
    1733           0 :       if (node->pkt->pkttype == PKT_PUBLIC_KEY
    1734           0 :           || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
    1735             :         {
    1736             :           char *desc;
    1737             : 
    1738           0 :           pk = node->pkt->pkt.public_key;
    1739           0 :           keyid_from_pk (pk, subid);
    1740             : 
    1741           0 :           xfree (hexgrip);
    1742           0 :           err = hexkeygrip_from_pk (pk, &hexgrip);
    1743           0 :           if (err)
    1744           0 :             goto leave;
    1745             : 
    1746           0 :           desc = gpg_format_keydesc (pk, FORMAT_KEYDESC_NORMAL, 1);
    1747           0 :           err = agent_passwd (ctrl, hexgrip, desc, 0,
    1748             :                               &cache_nonce, &passwd_nonce);
    1749           0 :           xfree (desc);
    1750             : 
    1751           0 :           if (err)
    1752           0 :             log_log ((gpg_err_code (err) == GPG_ERR_CANCELED
    1753           0 :                       || gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
    1754             :                      ? GPGRT_LOG_INFO : GPGRT_LOG_ERROR,
    1755           0 :                      _("key %s: error changing passphrase: %s\n"),
    1756             :                        keystr_with_sub (keyid, subid),
    1757             :                        gpg_strerror (err));
    1758           0 :           if (gpg_err_code (err) == GPG_ERR_FULLY_CANCELED)
    1759           0 :             break;
    1760             :         }
    1761             :     }
    1762             : 
    1763             :  leave:
    1764           0 :   xfree (hexgrip);
    1765           0 :   xfree (cache_nonce);
    1766           0 :   xfree (passwd_nonce);
    1767           0 :   return err;
    1768             : }
    1769             : 
    1770             : 
    1771             : 
    1772             : /* Fix various problems in the keyblock.  Returns true if the keyblock
    1773             :    was changed.  Note that a pointer to the keyblock must be given and
    1774             :    the function may change it (i.e. replacing the first node).  */
    1775             : static int
    1776           2 : fix_keyblock (kbnode_t *keyblockp)
    1777             : {
    1778           2 :   int changed = 0;
    1779             : 
    1780           2 :   if (collapse_uids (keyblockp))
    1781           0 :     changed++;
    1782           2 :   if (check_all_keysigs (*keyblockp, 0, 1))
    1783           0 :     changed++;
    1784           2 :   reorder_keyblock (*keyblockp);
    1785             :   /* If we modified the keyblock, make sure the flags are right. */
    1786           2 :   if (changed)
    1787           0 :     merge_keys_and_selfsig (*keyblockp);
    1788             : 
    1789           2 :   return changed;
    1790             : }
    1791             : 
    1792             : 
    1793             : static int
    1794           0 : parse_sign_type (const char *str, int *localsig, int *nonrevokesig,
    1795             :                  int *trustsig)
    1796             : {
    1797           0 :   const char *p = str;
    1798             : 
    1799           0 :   while (*p)
    1800             :     {
    1801           0 :       if (ascii_strncasecmp (p, "l", 1) == 0)
    1802             :         {
    1803           0 :           *localsig = 1;
    1804           0 :           p++;
    1805             :         }
    1806           0 :       else if (ascii_strncasecmp (p, "nr", 2) == 0)
    1807             :         {
    1808           0 :           *nonrevokesig = 1;
    1809           0 :           p += 2;
    1810             :         }
    1811           0 :       else if (ascii_strncasecmp (p, "t", 1) == 0)
    1812             :         {
    1813           0 :           *trustsig = 1;
    1814           0 :           p++;
    1815             :         }
    1816             :       else
    1817           0 :         return 0;
    1818             :     }
    1819             : 
    1820           0 :   return 1;
    1821             : }
    1822             : 
    1823             : 
    1824             : 
    1825             : /*
    1826             :  * Menu driven key editor.  If seckey_check is true, then a secret key
    1827             :  * that matches username will be looked for.  If it is false, not all
    1828             :  * commands will be available.
    1829             :  *
    1830             :  * Note: to keep track of certain selections we use node->mark MARKBIT_xxxx.
    1831             :  */
    1832             : 
    1833             : /* Need an SK for this command */
    1834             : #define KEYEDIT_NEED_SK 1
    1835             : /* Cannot be viewing the SK for this command */
    1836             : #define KEYEDIT_NOT_SK  2
    1837             : /* Must be viewing the SK for this command */
    1838             : #define KEYEDIT_ONLY_SK 4
    1839             : /* Match the tail of the string */
    1840             : #define KEYEDIT_TAIL_MATCH 8
    1841             : 
    1842             : enum cmdids
    1843             : {
    1844             :   cmdNONE = 0,
    1845             :   cmdQUIT, cmdHELP, cmdFPR, cmdLIST, cmdSELUID, cmdCHECK, cmdSIGN,
    1846             :   cmdREVSIG, cmdREVKEY, cmdREVUID, cmdDELSIG, cmdPRIMARY, cmdDEBUG,
    1847             :   cmdSAVE, cmdADDUID, cmdADDPHOTO, cmdDELUID, cmdADDKEY, cmdDELKEY,
    1848             :   cmdADDREVOKER, cmdTOGGLE, cmdSELKEY, cmdPASSWD, cmdTRUST, cmdPREF,
    1849             :   cmdEXPIRE, cmdCHANGEUSAGE, cmdBACKSIGN,
    1850             : #ifndef NO_TRUST_MODELS
    1851             :   cmdENABLEKEY, cmdDISABLEKEY,
    1852             : #endif /*!NO_TRUST_MODELS*/
    1853             :   cmdSHOWPREF,
    1854             :   cmdSETPREF, cmdPREFKS, cmdNOTATION, cmdINVCMD, cmdSHOWPHOTO, cmdUPDTRUST,
    1855             :   cmdCHKTRUST, cmdADDCARDKEY, cmdKEYTOCARD, cmdBKUPTOCARD,
    1856             :   cmdCLEAN, cmdMINIMIZE, cmdGRIP, cmdNOP
    1857             : };
    1858             : 
    1859             : static struct
    1860             : {
    1861             :   const char *name;
    1862             :   enum cmdids id;
    1863             :   int flags;
    1864             :   const char *desc;
    1865             : } cmds[] =
    1866             : {
    1867             :   { "quit", cmdQUIT, 0, N_("quit this menu")},
    1868             :   { "q", cmdQUIT, 0, NULL},
    1869             :   { "save", cmdSAVE, 0, N_("save and quit")},
    1870             :   { "help", cmdHELP, 0, N_("show this help")},
    1871             :   { "?", cmdHELP, 0, NULL},
    1872             :   { "fpr", cmdFPR, 0, N_("show key fingerprint")},
    1873             :   { "grip", cmdGRIP, 0, N_("show the keygrip")},
    1874             :   { "list", cmdLIST, 0, N_("list key and user IDs")},
    1875             :   { "l", cmdLIST, 0, NULL},
    1876             :   { "uid", cmdSELUID, 0, N_("select user ID N")},
    1877             :   { "key", cmdSELKEY, 0, N_("select subkey N")},
    1878             :   { "check", cmdCHECK, 0, N_("check signatures")},
    1879             :   { "c", cmdCHECK, 0, NULL},
    1880             :   { "change-usage", cmdCHANGEUSAGE, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, NULL},
    1881             :   { "cross-certify", cmdBACKSIGN, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, NULL},
    1882             :   { "backsign", cmdBACKSIGN, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, NULL},
    1883             :   { "sign", cmdSIGN, KEYEDIT_NOT_SK | KEYEDIT_TAIL_MATCH,
    1884             :     N_("sign selected user IDs [* see below for related commands]")},
    1885             :   { "s", cmdSIGN, KEYEDIT_NOT_SK, NULL},
    1886             :     /* "lsign" and friends will never match since "sign" comes first
    1887             :        and it is a tail match.  They are just here so they show up in
    1888             :        the help menu. */
    1889             :   { "lsign", cmdNOP, 0, N_("sign selected user IDs locally")},
    1890             :   { "tsign", cmdNOP, 0, N_("sign selected user IDs with a trust signature")},
    1891             :   { "nrsign", cmdNOP, 0,
    1892             :     N_("sign selected user IDs with a non-revocable signature")},
    1893             :   { "debug", cmdDEBUG, 0, NULL},
    1894             :   { "adduid", cmdADDUID, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, N_("add a user ID")},
    1895             :   { "addphoto", cmdADDPHOTO, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
    1896             :     N_("add a photo ID")},
    1897             :   { "deluid", cmdDELUID, KEYEDIT_NOT_SK, N_("delete selected user IDs")},
    1898             :     /* delphoto is really deluid in disguise */
    1899             :   { "delphoto", cmdDELUID, KEYEDIT_NOT_SK, NULL},
    1900             :   { "addkey", cmdADDKEY, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, N_("add a subkey")},
    1901             : #ifdef ENABLE_CARD_SUPPORT
    1902             :   { "addcardkey", cmdADDCARDKEY, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
    1903             :     N_("add a key to a smartcard")},
    1904             :   { "keytocard", cmdKEYTOCARD, KEYEDIT_NEED_SK | KEYEDIT_ONLY_SK,
    1905             :     N_("move a key to a smartcard")},
    1906             :   { "bkuptocard", cmdBKUPTOCARD, KEYEDIT_NEED_SK | KEYEDIT_ONLY_SK,
    1907             :     N_("move a backup key to a smartcard")},
    1908             : #endif /*ENABLE_CARD_SUPPORT */
    1909             :   { "delkey", cmdDELKEY, KEYEDIT_NOT_SK, N_("delete selected subkeys")},
    1910             :   { "addrevoker", cmdADDREVOKER, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
    1911             :     N_("add a revocation key")},
    1912             :   { "delsig", cmdDELSIG, KEYEDIT_NOT_SK,
    1913             :     N_("delete signatures from the selected user IDs")},
    1914             :   { "expire", cmdEXPIRE, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
    1915             :     N_("change the expiration date for the key or selected subkeys")},
    1916             :   { "primary", cmdPRIMARY, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
    1917             :     N_("flag the selected user ID as primary")},
    1918             :   { "toggle", cmdTOGGLE, KEYEDIT_NEED_SK, NULL},  /* Dummy command.  */
    1919             :   { "t", cmdTOGGLE, KEYEDIT_NEED_SK, NULL},
    1920             :   { "pref", cmdPREF, KEYEDIT_NOT_SK, N_("list preferences (expert)")},
    1921             :   { "showpref", cmdSHOWPREF, KEYEDIT_NOT_SK, N_("list preferences (verbose)")},
    1922             :   { "setpref", cmdSETPREF, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
    1923             :     N_("set preference list for the selected user IDs")},
    1924             :   { "updpref", cmdSETPREF, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, NULL},
    1925             :   { "keyserver", cmdPREFKS, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
    1926             :     N_("set the preferred keyserver URL for the selected user IDs")},
    1927             :   { "notation", cmdNOTATION, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
    1928             :     N_("set a notation for the selected user IDs")},
    1929             :   { "passwd", cmdPASSWD, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
    1930             :     N_("change the passphrase")},
    1931             :   { "password", cmdPASSWD, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, NULL},
    1932             : #ifndef NO_TRUST_MODELS
    1933             :   { "trust", cmdTRUST, KEYEDIT_NOT_SK, N_("change the ownertrust")},
    1934             : #endif /*!NO_TRUST_MODELS*/
    1935             :   { "revsig", cmdREVSIG, KEYEDIT_NOT_SK,
    1936             :     N_("revoke signatures on the selected user IDs")},
    1937             :   { "revuid", cmdREVUID, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
    1938             :     N_("revoke selected user IDs")},
    1939             :   { "revphoto", cmdREVUID, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK, NULL},
    1940             :   { "revkey", cmdREVKEY, KEYEDIT_NOT_SK | KEYEDIT_NEED_SK,
    1941             :     N_("revoke key or selected subkeys")},
    1942             : #ifndef NO_TRUST_MODELS
    1943             :   { "enable", cmdENABLEKEY, KEYEDIT_NOT_SK, N_("enable key")},
    1944             :   { "disable", cmdDISABLEKEY, KEYEDIT_NOT_SK, N_("disable key")},
    1945             : #endif /*!NO_TRUST_MODELS*/
    1946             :   { "showphoto", cmdSHOWPHOTO, 0, N_("show selected photo IDs")},
    1947             :   { "clean", cmdCLEAN, KEYEDIT_NOT_SK,
    1948             :     N_("compact unusable user IDs and remove unusable signatures from key")},
    1949             :   { "minimize", cmdMINIMIZE, KEYEDIT_NOT_SK,
    1950             :     N_("compact unusable user IDs and remove all signatures from key")},
    1951             : 
    1952             :   { NULL, cmdNONE, 0, NULL}
    1953             : };
    1954             : 
    1955             : 
    1956             : 
    1957             : #ifdef HAVE_LIBREADLINE
    1958             : 
    1959             : /*
    1960             :    These two functions are used by readline for command completion.
    1961             :  */
    1962             : 
    1963             : static char *
    1964           0 : command_generator (const char *text, int state)
    1965             : {
    1966             :   static int list_index, len;
    1967             :   const char *name;
    1968             : 
    1969             :   /* If this is a new word to complete, initialize now.  This includes
    1970             :      saving the length of TEXT for efficiency, and initializing the
    1971             :      index variable to 0. */
    1972           0 :   if (!state)
    1973             :     {
    1974           0 :       list_index = 0;
    1975           0 :       len = strlen (text);
    1976             :     }
    1977             : 
    1978             :   /* Return the next partial match */
    1979           0 :   while ((name = cmds[list_index].name))
    1980             :     {
    1981             :       /* Only complete commands that have help text */
    1982           0 :       if (cmds[list_index++].desc && strncmp (name, text, len) == 0)
    1983           0 :         return strdup (name);
    1984             :     }
    1985             : 
    1986           0 :   return NULL;
    1987             : }
    1988             : 
    1989             : static char **
    1990           0 : keyedit_completion (const char *text, int start, int end)
    1991             : {
    1992             :   /* If we are at the start of a line, we try and command-complete.
    1993             :      If not, just do nothing for now. */
    1994             : 
    1995             :   (void) end;
    1996             : 
    1997           0 :   if (start == 0)
    1998           0 :     return rl_completion_matches (text, command_generator);
    1999             : 
    2000           0 :   rl_attempted_completion_over = 1;
    2001             : 
    2002           0 :   return NULL;
    2003             : }
    2004             : #endif /* HAVE_LIBREADLINE */
    2005             : 
    2006             : 
    2007             : 
    2008             : /* Main function of the menu driven key editor.  */
    2009             : void
    2010           0 : keyedit_menu (ctrl_t ctrl, const char *username, strlist_t locusr,
    2011             :               strlist_t commands, int quiet, int seckey_check)
    2012             : {
    2013           0 :   enum cmdids cmd = 0;
    2014           0 :   gpg_error_t err = 0;
    2015           0 :   KBNODE keyblock = NULL;
    2016           0 :   KEYDB_HANDLE kdbhd = NULL;
    2017           0 :   int have_seckey = 0;
    2018           0 :   char *answer = NULL;
    2019           0 :   int redisplay = 1;
    2020           0 :   int modified = 0;
    2021           0 :   int sec_shadowing = 0;
    2022           0 :   int run_subkey_warnings = 0;
    2023           0 :   int have_commands = !!commands;
    2024             : 
    2025           0 :   if (opt.command_fd != -1)
    2026             :     ;
    2027           0 :   else if (opt.batch && !have_commands)
    2028             :     {
    2029           0 :       log_error (_("can't do this in batch mode\n"));
    2030           0 :       goto leave;
    2031             :     }
    2032             : 
    2033             : #ifdef HAVE_W32_SYSTEM
    2034             :   /* Due to Windows peculiarities we need to make sure that the
    2035             :      trustdb stale check is done before we open another file
    2036             :      (i.e. by searching for a key).  In theory we could make sure
    2037             :      that the files are closed after use but the open/close caches
    2038             :      inhibits that and flushing the cache right before the stale
    2039             :      check is not easy to implement.  Thus we take the easy way out
    2040             :      and run the stale check as early as possible.  Note, that for
    2041             :      non- W32 platforms it is run indirectly trough a call to
    2042             :      get_validity ().  */
    2043             :   check_trustdb_stale (ctrl);
    2044             : #endif
    2045             : 
    2046             :   /* Get the public key */
    2047           0 :   err = get_pubkey_byname (ctrl, NULL, NULL, username, &keyblock, &kdbhd, 1, 1);
    2048           0 :   if (err)
    2049             :     {
    2050           0 :       log_error (_("key \"%s\" not found: %s\n"), username, gpg_strerror (err));
    2051           0 :       goto leave;
    2052             :     }
    2053             : 
    2054           0 :   if (fix_keyblock (&keyblock))
    2055           0 :     modified++;
    2056             : 
    2057             :   /* See whether we have a matching secret key.  */
    2058           0 :   if (seckey_check)
    2059             :     {
    2060           0 :       have_seckey = !agent_probe_any_secret_key (ctrl, keyblock);
    2061           0 :       if (have_seckey && !quiet)
    2062           0 :         tty_printf (_("Secret key is available.\n"));
    2063             :     }
    2064             : 
    2065             :   /* Main command loop.  */
    2066             :   for (;;)
    2067             :     {
    2068             :       int i, arg_number, photo;
    2069           0 :       const char *arg_string = "";
    2070             :       char *p;
    2071           0 :       PKT_public_key *pk = keyblock->pkt->pkt.public_key;
    2072             : 
    2073           0 :       tty_printf ("\n");
    2074             : 
    2075           0 :       if (redisplay && !quiet)
    2076             :         {
    2077             :           /* Show using flags: with_revoker, with_subkeys.  */
    2078           0 :           show_key_with_all_names (ctrl, NULL, keyblock, 0, 1, 0, 1, 0, 0);
    2079           0 :           tty_printf ("\n");
    2080           0 :           redisplay = 0;
    2081             :         }
    2082             : 
    2083           0 :       if (run_subkey_warnings)
    2084             :         {
    2085           0 :           run_subkey_warnings = 0;
    2086           0 :           if (!count_selected_keys (keyblock))
    2087           0 :             subkey_expire_warning (keyblock);
    2088             :         }
    2089             : 
    2090             :       do
    2091             :         {
    2092           0 :           xfree (answer);
    2093           0 :           if (have_commands)
    2094             :             {
    2095           0 :               if (commands)
    2096             :                 {
    2097           0 :                   answer = xstrdup (commands->d);
    2098           0 :                   commands = commands->next;
    2099             :                 }
    2100           0 :               else if (opt.batch)
    2101             :                 {
    2102           0 :                   answer = xstrdup ("quit");
    2103             :                 }
    2104             :               else
    2105           0 :                 have_commands = 0;
    2106             :             }
    2107           0 :           if (!have_commands)
    2108             :             {
    2109             : #ifdef HAVE_LIBREADLINE
    2110           0 :               tty_enable_completion (keyedit_completion);
    2111             : #endif
    2112           0 :               answer = cpr_get_no_help ("keyedit.prompt", GPG_NAME "> ");
    2113           0 :               cpr_kill_prompt ();
    2114           0 :               tty_disable_completion ();
    2115             :             }
    2116           0 :           trim_spaces (answer);
    2117             :         }
    2118           0 :       while (*answer == '#');
    2119             : 
    2120           0 :       arg_number = 0; /* Here is the init which egcc complains about.  */
    2121           0 :       photo = 0;      /* Same here. */
    2122           0 :       if (!*answer)
    2123           0 :         cmd = cmdLIST;
    2124           0 :       else if (*answer == CONTROL_D)
    2125           0 :         cmd = cmdQUIT;
    2126           0 :       else if (digitp (answer))
    2127             :         {
    2128           0 :           cmd = cmdSELUID;
    2129           0 :           arg_number = atoi (answer);
    2130             :         }
    2131             :       else
    2132             :         {
    2133           0 :           if ((p = strchr (answer, ' ')))
    2134             :             {
    2135           0 :               *p++ = 0;
    2136           0 :               trim_spaces (answer);
    2137           0 :               trim_spaces (p);
    2138           0 :               arg_number = atoi (p);
    2139           0 :               arg_string = p;
    2140             :             }
    2141             : 
    2142           0 :           for (i = 0; cmds[i].name; i++)
    2143             :             {
    2144           0 :               if (cmds[i].flags & KEYEDIT_TAIL_MATCH)
    2145             :                 {
    2146           0 :                   size_t l = strlen (cmds[i].name);
    2147           0 :                   size_t a = strlen (answer);
    2148           0 :                   if (a >= l)
    2149             :                     {
    2150           0 :                       if (!ascii_strcasecmp (&answer[a - l], cmds[i].name))
    2151             :                         {
    2152           0 :                           answer[a - l] = '\0';
    2153           0 :                           break;
    2154             :                         }
    2155             :                     }
    2156             :                 }
    2157           0 :               else if (!ascii_strcasecmp (answer, cmds[i].name))
    2158           0 :                 break;
    2159             :             }
    2160           0 :           if ((cmds[i].flags & KEYEDIT_NEED_SK) && !have_seckey)
    2161             :             {
    2162           0 :               tty_printf (_("Need the secret key to do this.\n"));
    2163           0 :               cmd = cmdNOP;
    2164             :             }
    2165             :           else
    2166           0 :             cmd = cmds[i].id;
    2167             :         }
    2168             : 
    2169             :       /* Dispatch the command.  */
    2170           0 :       switch (cmd)
    2171             :         {
    2172             :         case cmdHELP:
    2173           0 :           for (i = 0; cmds[i].name; i++)
    2174             :             {
    2175           0 :               if ((cmds[i].flags & KEYEDIT_NEED_SK) && !have_seckey)
    2176             :                 ; /* Skip those item if we do not have the secret key.  */
    2177           0 :               else if (cmds[i].desc)
    2178           0 :                 tty_printf ("%-11s %s\n", cmds[i].name, _(cmds[i].desc));
    2179             :             }
    2180             : 
    2181           0 :           tty_printf ("\n");
    2182           0 :           tty_printf
    2183           0 :             (_("* The 'sign' command may be prefixed with an 'l' for local "
    2184             :                "signatures (lsign),\n"
    2185             :                "  a 't' for trust signatures (tsign), an 'nr' for "
    2186             :                "non-revocable signatures\n"
    2187             :                "  (nrsign), or any combination thereof (ltsign, "
    2188             :                "tnrsign, etc.).\n"));
    2189           0 :           break;
    2190             : 
    2191             :         case cmdLIST:
    2192           0 :           redisplay = 1;
    2193           0 :           break;
    2194             : 
    2195             :         case cmdFPR:
    2196           0 :           show_key_and_fingerprint
    2197           0 :             (keyblock, (*arg_string == '*'
    2198           0 :                         && (!arg_string[1] || spacep (arg_string + 1))));
    2199           0 :           break;
    2200             : 
    2201             :         case cmdGRIP:
    2202           0 :           show_key_and_grip (keyblock);
    2203           0 :           break;
    2204             : 
    2205             :         case cmdSELUID:
    2206           0 :           if (strlen (arg_string) == NAMEHASH_LEN * 2)
    2207           0 :             redisplay = menu_select_uid_namehash (keyblock, arg_string);
    2208             :           else
    2209             :             {
    2210           0 :               if (*arg_string == '*'
    2211           0 :                   && (!arg_string[1] || spacep (arg_string + 1)))
    2212           0 :                 arg_number = -1;        /* Select all. */
    2213           0 :               redisplay = menu_select_uid (keyblock, arg_number);
    2214             :             }
    2215           0 :           break;
    2216             : 
    2217             :         case cmdSELKEY:
    2218             :           {
    2219           0 :             if (*arg_string == '*'
    2220           0 :                 && (!arg_string[1] || spacep (arg_string + 1)))
    2221           0 :               arg_number = -1;  /* Select all. */
    2222           0 :             if (menu_select_key (keyblock, arg_number, p))
    2223           0 :               redisplay = 1;
    2224             :           }
    2225           0 :           break;
    2226             : 
    2227             :         case cmdCHECK:
    2228           0 :           if (check_all_keysigs (keyblock, count_selected_uids (keyblock),
    2229           0 :                                  !strcmp (arg_string, "selfsig")))
    2230           0 :             modified = 1;
    2231           0 :           break;
    2232             : 
    2233             :         case cmdSIGN:
    2234             :           {
    2235           0 :             int localsig = 0, nonrevokesig = 0, trustsig = 0, interactive = 0;
    2236             : 
    2237           0 :             if (pk->flags.revoked)
    2238             :               {
    2239           0 :                 tty_printf (_("Key is revoked."));
    2240             : 
    2241           0 :                 if (opt.expert)
    2242             :                   {
    2243           0 :                     tty_printf ("  ");
    2244           0 :                     if (!cpr_get_answer_is_yes
    2245             :                         ("keyedit.sign_revoked.okay",
    2246           0 :                          _("Are you sure you still want to sign it? (y/N) ")))
    2247           0 :                       break;
    2248             :                   }
    2249             :                 else
    2250             :                   {
    2251           0 :                     tty_printf (_("  Unable to sign.\n"));
    2252           0 :                     break;
    2253             :                   }
    2254             :               }
    2255             : 
    2256           0 :             if (count_uids (keyblock) > 1 && !count_selected_uids (keyblock))
    2257             :               {
    2258             :                 int result;
    2259           0 :                 if (opt.only_sign_text_ids)
    2260           0 :                   result = cpr_get_answer_is_yes
    2261             :                     ("keyedit.sign_all.okay",
    2262           0 :                      _("Really sign all user IDs? (y/N) "));
    2263             :                 else
    2264           0 :                   result = cpr_get_answer_is_yes
    2265             :                     ("keyedit.sign_all.okay",
    2266           0 :                      _("Really sign all text user IDs? (y/N) "));
    2267             : 
    2268           0 :                 if (! result)
    2269             :                   {
    2270           0 :                     if (opt.interactive)
    2271           0 :                       interactive = 1;
    2272             :                     else
    2273             :                       {
    2274           0 :                         tty_printf (_("Hint: Select the user IDs to sign\n"));
    2275           0 :                         have_commands = 0;
    2276           0 :                         break;
    2277             :                       }
    2278             : 
    2279             :                   }
    2280             :               }
    2281             :             /* What sort of signing are we doing? */
    2282           0 :             if (!parse_sign_type
    2283             :                 (answer, &localsig, &nonrevokesig, &trustsig))
    2284             :               {
    2285           0 :                 tty_printf (_("Unknown signature type '%s'\n"), answer);
    2286           0 :                 break;
    2287             :               }
    2288             : 
    2289           0 :             sign_uids (ctrl, NULL, keyblock, locusr, &modified,
    2290             :                        localsig, nonrevokesig, trustsig, interactive, 0);
    2291             :           }
    2292           0 :           break;
    2293             : 
    2294             :         case cmdDEBUG:
    2295           0 :           dump_kbnode (keyblock);
    2296           0 :           break;
    2297             : 
    2298             :         case cmdTOGGLE:
    2299             :           /* The toggle command is a leftover from old gpg versions
    2300             :              where we worked with a secret and a public keyring.  It
    2301             :              is not necessary anymore but we keep this command for the
    2302             :              sake of scripts using it.  */
    2303           0 :           redisplay = 1;
    2304           0 :           break;
    2305             : 
    2306             :         case cmdADDPHOTO:
    2307           0 :           if (RFC2440)
    2308             :             {
    2309           0 :               tty_printf (_("This command is not allowed while in %s mode.\n"),
    2310             :                           compliance_option_string ());
    2311           0 :               break;
    2312             :             }
    2313           0 :           photo = 1;
    2314             :           /* fall through */
    2315             :         case cmdADDUID:
    2316           0 :           if (menu_adduid (ctrl, keyblock, photo, arg_string, NULL))
    2317             :             {
    2318           0 :               update_trust = 1;
    2319           0 :               redisplay = 1;
    2320           0 :               modified = 1;
    2321           0 :               merge_keys_and_selfsig (keyblock);
    2322             :             }
    2323           0 :           break;
    2324             : 
    2325             :         case cmdDELUID:
    2326             :           {
    2327             :             int n1;
    2328             : 
    2329           0 :             if (!(n1 = count_selected_uids (keyblock)))
    2330             :               {
    2331           0 :                 tty_printf (_("You must select at least one user ID.\n"));
    2332           0 :                 if (!opt.expert)
    2333           0 :                   tty_printf (_("(Use the '%s' command.)\n"), "uid");
    2334             :               }
    2335           0 :             else if (real_uids_left (keyblock) < 1)
    2336           0 :               tty_printf (_("You can't delete the last user ID!\n"));
    2337           0 :             else if (cpr_get_answer_is_yes
    2338             :                      ("keyedit.remove.uid.okay",
    2339             :                       n1 > 1 ? _("Really remove all selected user IDs? (y/N) ")
    2340             :                       :        _("Really remove this user ID? (y/N) ")))
    2341             :               {
    2342           0 :                 menu_deluid (keyblock);
    2343           0 :                 redisplay = 1;
    2344           0 :                 modified = 1;
    2345             :               }
    2346             :           }
    2347           0 :           break;
    2348             : 
    2349             :         case cmdDELSIG:
    2350             :           {
    2351             :             int n1;
    2352             : 
    2353           0 :             if (!(n1 = count_selected_uids (keyblock)))
    2354             :               {
    2355           0 :                 tty_printf (_("You must select at least one user ID.\n"));
    2356           0 :                 if (!opt.expert)
    2357           0 :                   tty_printf (_("(Use the '%s' command.)\n"), "uid");
    2358             :               }
    2359           0 :             else if (menu_delsig (keyblock))
    2360             :               {
    2361             :                 /* No redisplay here, because it may scroll away some
    2362             :                  * of the status output of this command.  */
    2363           0 :                 modified = 1;
    2364             :               }
    2365             :           }
    2366           0 :           break;
    2367             : 
    2368             :         case cmdADDKEY:
    2369           0 :           if (!generate_subkeypair (ctrl, keyblock, NULL, NULL, NULL))
    2370             :             {
    2371           0 :               redisplay = 1;
    2372           0 :               modified = 1;
    2373           0 :               merge_keys_and_selfsig (keyblock);
    2374             :             }
    2375           0 :           break;
    2376             : 
    2377             : #ifdef ENABLE_CARD_SUPPORT
    2378             :         case cmdADDCARDKEY:
    2379           0 :           if (!card_generate_subkey (keyblock))
    2380             :             {
    2381           0 :               redisplay = 1;
    2382           0 :               modified = 1;
    2383           0 :               merge_keys_and_selfsig (keyblock);
    2384             :             }
    2385           0 :           break;
    2386             : 
    2387             :         case cmdKEYTOCARD:
    2388             :           {
    2389           0 :             KBNODE node = NULL;
    2390           0 :             switch (count_selected_keys (keyblock))
    2391             :               {
    2392             :               case 0:
    2393           0 :                 if (cpr_get_answer_is_yes
    2394             :                     ("keyedit.keytocard.use_primary",
    2395             :                      /* TRANSLATORS: Please take care: This is about
    2396             :                         moving the key and not about removing it.  */
    2397           0 :                      _("Really move the primary key? (y/N) ")))
    2398           0 :                   node = keyblock;
    2399           0 :                 break;
    2400             :               case 1:
    2401           0 :                 for (node = keyblock; node; node = node->next)
    2402             :                   {
    2403           0 :                     if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
    2404           0 :                         && node->flag & NODFLG_SELKEY)
    2405           0 :                       break;
    2406             :                   }
    2407           0 :                 break;
    2408             :               default:
    2409           0 :                 tty_printf (_("You must select exactly one key.\n"));
    2410           0 :                 break;
    2411             :               }
    2412           0 :             if (node)
    2413             :               {
    2414           0 :                 PKT_public_key *xxpk = node->pkt->pkt.public_key;
    2415           0 :                 if (card_store_subkey (node, xxpk ? xxpk->pubkey_usage : 0))
    2416             :                   {
    2417           0 :                     redisplay = 1;
    2418           0 :                     sec_shadowing = 1;
    2419             :                   }
    2420             :               }
    2421             :           }
    2422           0 :           break;
    2423             : 
    2424             :         case cmdBKUPTOCARD:
    2425             :           {
    2426             :             /* Ask for a filename, check whether this is really a
    2427             :                backup key as generated by the card generation, parse
    2428             :                that key and store it on card. */
    2429             :             KBNODE node;
    2430             :             char *fname;
    2431             :             PACKET *pkt;
    2432             :             IOBUF a;
    2433             : 
    2434           0 :             if (!*arg_string)
    2435             :               {
    2436           0 :                 tty_printf (_("Command expects a filename argument\n"));
    2437           0 :                 break;
    2438             :               }
    2439             : 
    2440           0 :             if (*arg_string == DIRSEP_C)
    2441           0 :               fname = xstrdup (arg_string);
    2442           0 :             else if (*arg_string == '~')
    2443           0 :               fname = make_filename (arg_string, NULL);
    2444             :             else
    2445           0 :               fname = make_filename (gnupg_homedir (), arg_string, NULL);
    2446             : 
    2447             :             /* Open that file.  */
    2448           0 :             a = iobuf_open (fname);
    2449           0 :             if (a && is_secured_file (iobuf_get_fd (a)))
    2450             :               {
    2451           0 :                 iobuf_close (a);
    2452           0 :                 a = NULL;
    2453           0 :                 gpg_err_set_errno (EPERM);
    2454             :               }
    2455           0 :             if (!a)
    2456             :               {
    2457           0 :                 tty_printf (_("Can't open '%s': %s\n"),
    2458           0 :                             fname, strerror (errno));
    2459           0 :                 xfree (fname);
    2460           0 :                 break;
    2461             :               }
    2462             : 
    2463             :             /* Parse and check that file.  */
    2464           0 :             pkt = xmalloc (sizeof *pkt);
    2465           0 :             init_packet (pkt);
    2466           0 :             err = parse_packet (a, pkt);
    2467           0 :             iobuf_close (a);
    2468           0 :             iobuf_ioctl (NULL, IOBUF_IOCTL_INVALIDATE_CACHE, 0, (char *) fname);
    2469           0 :             if (!err && pkt->pkttype != PKT_SECRET_KEY
    2470           0 :                 && pkt->pkttype != PKT_SECRET_SUBKEY)
    2471           0 :               err = GPG_ERR_NO_SECKEY;
    2472           0 :             if (err)
    2473             :               {
    2474           0 :                 tty_printf (_("Error reading backup key from '%s': %s\n"),
    2475             :                             fname, gpg_strerror (err));
    2476           0 :                 xfree (fname);
    2477           0 :                 free_packet (pkt);
    2478           0 :                 xfree (pkt);
    2479           0 :                 break;
    2480             :               }
    2481             : 
    2482           0 :             xfree (fname);
    2483           0 :             node = new_kbnode (pkt);
    2484             : 
    2485             :             /* Transfer it to gpg-agent which handles secret keys.  */
    2486           0 :             err = transfer_secret_keys (ctrl, NULL, node, 1, 1);
    2487             : 
    2488             :             /* Treat the pkt as a public key.  */
    2489           0 :             pkt->pkttype = PKT_PUBLIC_KEY;
    2490             : 
    2491             :             /* Ask gpg-agent to store the secret key to card.  */
    2492           0 :             if (card_store_subkey (node, 0))
    2493             :               {
    2494           0 :                 redisplay = 1;
    2495           0 :                 sec_shadowing = 1;
    2496             :               }
    2497           0 :             release_kbnode (node);
    2498             :           }
    2499           0 :           break;
    2500             : 
    2501             : #endif /* ENABLE_CARD_SUPPORT */
    2502             : 
    2503             :         case cmdDELKEY:
    2504             :           {
    2505             :             int n1;
    2506             : 
    2507           0 :             if (!(n1 = count_selected_keys (keyblock)))
    2508             :               {
    2509           0 :                 tty_printf (_("You must select at least one key.\n"));
    2510           0 :                 if (!opt.expert)
    2511           0 :                   tty_printf (_("(Use the '%s' command.)\n"), "key");
    2512             :               }
    2513           0 :             else if (!cpr_get_answer_is_yes
    2514             :                      ("keyedit.remove.subkey.okay",
    2515             :                       n1 > 1 ? _("Do you really want to delete the "
    2516             :                                  "selected keys? (y/N) ")
    2517             :                       :  _("Do you really want to delete this key? (y/N) ")))
    2518             :               ;
    2519             :             else
    2520             :               {
    2521           0 :                 menu_delkey (keyblock);
    2522           0 :                 redisplay = 1;
    2523           0 :                 modified = 1;
    2524             :               }
    2525             :           }
    2526           0 :           break;
    2527             : 
    2528             :         case cmdADDREVOKER:
    2529             :           {
    2530           0 :             int sensitive = 0;
    2531             : 
    2532           0 :             if (ascii_strcasecmp (arg_string, "sensitive") == 0)
    2533           0 :               sensitive = 1;
    2534           0 :             if (menu_addrevoker (ctrl, keyblock, sensitive))
    2535             :               {
    2536           0 :                 redisplay = 1;
    2537           0 :                 modified = 1;
    2538           0 :                 merge_keys_and_selfsig (keyblock);
    2539             :               }
    2540             :           }
    2541           0 :           break;
    2542             : 
    2543             :         case cmdREVUID:
    2544             :           {
    2545             :             int n1;
    2546             : 
    2547           0 :             if (!(n1 = count_selected_uids (keyblock)))
    2548             :               {
    2549           0 :                 tty_printf (_("You must select at least one user ID.\n"));
    2550           0 :                 if (!opt.expert)
    2551           0 :                   tty_printf (_("(Use the '%s' command.)\n"), "uid");
    2552             :               }
    2553           0 :             else if (cpr_get_answer_is_yes
    2554             :                      ("keyedit.revoke.uid.okay",
    2555             :                       n1 > 1 ? _("Really revoke all selected user IDs? (y/N) ")
    2556             :                       :        _("Really revoke this user ID? (y/N) ")))
    2557             :               {
    2558           0 :                 if (menu_revuid (ctrl, keyblock))
    2559             :                   {
    2560           0 :                     modified = 1;
    2561           0 :                     redisplay = 1;
    2562             :                   }
    2563             :               }
    2564             :           }
    2565           0 :           break;
    2566             : 
    2567             :         case cmdREVKEY:
    2568             :           {
    2569             :             int n1;
    2570             : 
    2571           0 :             if (!(n1 = count_selected_keys (keyblock)))
    2572             :               {
    2573           0 :                 if (cpr_get_answer_is_yes ("keyedit.revoke.subkey.okay",
    2574           0 :                                            _("Do you really want to revoke"
    2575             :                                              " the entire key? (y/N) ")))
    2576             :                   {
    2577           0 :                     if (menu_revkey (keyblock))
    2578           0 :                       modified = 1;
    2579             : 
    2580           0 :                     redisplay = 1;
    2581             :                   }
    2582             :               }
    2583           0 :             else if (cpr_get_answer_is_yes ("keyedit.revoke.subkey.okay",
    2584             :                                             n1 > 1 ?
    2585             :                                             _("Do you really want to revoke"
    2586             :                                               " the selected subkeys? (y/N) ")
    2587             :                                             : _("Do you really want to revoke"
    2588             :                                                 " this subkey? (y/N) ")))
    2589             :               {
    2590           0 :                 if (menu_revsubkey (keyblock))
    2591           0 :                   modified = 1;
    2592             : 
    2593           0 :                 redisplay = 1;
    2594             :               }
    2595             : 
    2596           0 :             if (modified)
    2597           0 :               merge_keys_and_selfsig (keyblock);
    2598             :           }
    2599           0 :           break;
    2600             : 
    2601             :         case cmdEXPIRE:
    2602           0 :           if (menu_expire (keyblock))
    2603             :             {
    2604           0 :               merge_keys_and_selfsig (keyblock);
    2605           0 :               run_subkey_warnings = 1;
    2606           0 :               modified = 1;
    2607           0 :               redisplay = 1;
    2608             :             }
    2609           0 :           break;
    2610             : 
    2611             :         case cmdCHANGEUSAGE:
    2612           0 :           if (menu_changeusage (keyblock))
    2613             :             {
    2614           0 :               merge_keys_and_selfsig (keyblock);
    2615           0 :               modified = 1;
    2616           0 :               redisplay = 1;
    2617             :             }
    2618           0 :           break;
    2619             : 
    2620             :         case cmdBACKSIGN:
    2621           0 :           if (menu_backsign (keyblock))
    2622             :             {
    2623           0 :               modified = 1;
    2624           0 :               redisplay = 1;
    2625             :             }
    2626           0 :           break;
    2627             : 
    2628             :         case cmdPRIMARY:
    2629           0 :           if (menu_set_primary_uid (keyblock))
    2630             :             {
    2631           0 :               merge_keys_and_selfsig (keyblock);
    2632           0 :               modified = 1;
    2633           0 :               redisplay = 1;
    2634             :             }
    2635           0 :           break;
    2636             : 
    2637             :         case cmdPASSWD:
    2638           0 :           change_passphrase (ctrl, keyblock);
    2639           0 :           break;
    2640             : 
    2641             : #ifndef NO_TRUST_MODELS
    2642             :         case cmdTRUST:
    2643           0 :           if (opt.trust_model == TM_EXTERNAL)
    2644             :             {
    2645           0 :               tty_printf (_("Owner trust may not be set while "
    2646             :                             "using a user provided trust database\n"));
    2647           0 :               break;
    2648             :             }
    2649             : 
    2650           0 :           show_key_with_all_names (ctrl, NULL, keyblock, 0, 0, 0, 1, 0, 0);
    2651           0 :           tty_printf ("\n");
    2652           0 :           if (edit_ownertrust (ctrl, find_kbnode (keyblock,
    2653           0 :                                             PKT_PUBLIC_KEY)->pkt->pkt.
    2654             :                                public_key, 1))
    2655             :             {
    2656           0 :               redisplay = 1;
    2657             :               /* No real need to set update_trust here as
    2658             :                  edit_ownertrust() calls revalidation_mark()
    2659             :                  anyway. */
    2660           0 :               update_trust = 1;
    2661             :             }
    2662           0 :           break;
    2663             : #endif /*!NO_TRUST_MODELS*/
    2664             : 
    2665             :         case cmdPREF:
    2666             :           {
    2667           0 :             int count = count_selected_uids (keyblock);
    2668           0 :             log_assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
    2669           0 :             show_names (ctrl, NULL, keyblock, keyblock->pkt->pkt.public_key,
    2670             :                         count ? NODFLG_SELUID : 0, 1);
    2671             :           }
    2672           0 :           break;
    2673             : 
    2674             :         case cmdSHOWPREF:
    2675             :           {
    2676           0 :             int count = count_selected_uids (keyblock);
    2677           0 :             log_assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
    2678           0 :             show_names (ctrl, NULL, keyblock, keyblock->pkt->pkt.public_key,
    2679             :                         count ? NODFLG_SELUID : 0, 2);
    2680             :           }
    2681           0 :           break;
    2682             : 
    2683             :         case cmdSETPREF:
    2684             :           {
    2685             :             PKT_user_id *tempuid;
    2686             : 
    2687           0 :             keygen_set_std_prefs (!*arg_string ? "default" : arg_string, 0);
    2688             : 
    2689           0 :             tempuid = keygen_get_std_prefs ();
    2690           0 :             tty_printf (_("Set preference list to:\n"));
    2691           0 :             show_prefs (tempuid, NULL, 1);
    2692           0 :             free_user_id (tempuid);
    2693             : 
    2694           0 :             if (cpr_get_answer_is_yes
    2695             :                 ("keyedit.setpref.okay",
    2696           0 :                  count_selected_uids (keyblock) ?
    2697             :                  _("Really update the preferences"
    2698             :                    " for the selected user IDs? (y/N) ")
    2699             :                  : _("Really update the preferences? (y/N) ")))
    2700             :               {
    2701           0 :                 if (menu_set_preferences (keyblock))
    2702             :                   {
    2703           0 :                     merge_keys_and_selfsig (keyblock);
    2704           0 :                     modified = 1;
    2705           0 :                     redisplay = 1;
    2706             :                   }
    2707             :               }
    2708             :           }
    2709           0 :           break;
    2710             : 
    2711             :         case cmdPREFKS:
    2712           0 :           if (menu_set_keyserver_url (*arg_string ? arg_string : NULL,
    2713             :                                       keyblock))
    2714             :             {
    2715           0 :               merge_keys_and_selfsig (keyblock);
    2716           0 :               modified = 1;
    2717           0 :               redisplay = 1;
    2718             :             }
    2719           0 :           break;
    2720             : 
    2721             :         case cmdNOTATION:
    2722           0 :           if (menu_set_notation (*arg_string ? arg_string : NULL,
    2723             :                                  keyblock))
    2724             :             {
    2725           0 :               merge_keys_and_selfsig (keyblock);
    2726           0 :               modified = 1;
    2727           0 :               redisplay = 1;
    2728             :             }
    2729           0 :           break;
    2730             : 
    2731             :         case cmdNOP:
    2732           0 :           break;
    2733             : 
    2734             :         case cmdREVSIG:
    2735           0 :           if (menu_revsig (keyblock))
    2736             :             {
    2737           0 :               redisplay = 1;
    2738           0 :               modified = 1;
    2739             :             }
    2740           0 :           break;
    2741             : 
    2742             : #ifndef NO_TRUST_MODELS
    2743             :         case cmdENABLEKEY:
    2744             :         case cmdDISABLEKEY:
    2745           0 :           if (enable_disable_key (keyblock, cmd == cmdDISABLEKEY))
    2746             :             {
    2747           0 :               redisplay = 1;
    2748           0 :               modified = 1;
    2749             :             }
    2750           0 :           break;
    2751             : #endif /*!NO_TRUST_MODELS*/
    2752             : 
    2753             :         case cmdSHOWPHOTO:
    2754           0 :           menu_showphoto (ctrl, keyblock);
    2755           0 :           break;
    2756             : 
    2757             :         case cmdCLEAN:
    2758           0 :           if (menu_clean (keyblock, 0))
    2759           0 :             redisplay = modified = 1;
    2760           0 :           break;
    2761             : 
    2762             :         case cmdMINIMIZE:
    2763           0 :           if (menu_clean (keyblock, 1))
    2764           0 :             redisplay = modified = 1;
    2765           0 :           break;
    2766             : 
    2767             :         case cmdQUIT:
    2768           0 :           if (have_commands)
    2769           0 :             goto leave;
    2770           0 :           if (!modified && !sec_shadowing)
    2771           0 :             goto leave;
    2772           0 :           if (!cpr_get_answer_is_yes ("keyedit.save.okay",
    2773           0 :                                       _("Save changes? (y/N) ")))
    2774             :             {
    2775           0 :               if (cpr_enabled ()
    2776           0 :                   || cpr_get_answer_is_yes ("keyedit.cancel.okay",
    2777           0 :                                             _("Quit without saving? (y/N) ")))
    2778             :                 goto leave;
    2779           0 :               break;
    2780             :             }
    2781             :           /* fall through */
    2782             :         case cmdSAVE:
    2783           0 :           if (modified)
    2784             :             {
    2785           0 :               err = keydb_update_keyblock (ctrl, kdbhd, keyblock);
    2786           0 :               if (err)
    2787             :                 {
    2788           0 :                   log_error (_("update failed: %s\n"), gpg_strerror (err));
    2789           0 :                   break;
    2790             :                 }
    2791             :             }
    2792             : 
    2793           0 :           if (sec_shadowing)
    2794             :             {
    2795           0 :               err = agent_scd_learn (NULL, 1);
    2796           0 :               if (err)
    2797             :                 {
    2798           0 :                   log_error (_("update failed: %s\n"), gpg_strerror (err));
    2799           0 :                   break;
    2800             :                 }
    2801             :             }
    2802             : 
    2803           0 :           if (!modified && !sec_shadowing)
    2804           0 :             tty_printf (_("Key not changed so no update needed.\n"));
    2805             : 
    2806           0 :           if (update_trust)
    2807             :             {
    2808           0 :               revalidation_mark ();
    2809           0 :               update_trust = 0;
    2810             :             }
    2811           0 :           goto leave;
    2812             : 
    2813             :         case cmdINVCMD:
    2814             :         default:
    2815           0 :           tty_printf ("\n");
    2816           0 :           tty_printf (_("Invalid command  (try \"help\")\n"));
    2817           0 :           break;
    2818             :         }
    2819           0 :     } /* End of the main command loop.  */
    2820             : 
    2821             :  leave:
    2822           0 :   release_kbnode (keyblock);
    2823           0 :   keydb_release (kdbhd);
    2824           0 :   xfree (answer);
    2825           0 : }
    2826             : 
    2827             : 
    2828             : /* Change the passphrase of the secret key identified by USERNAME.  */
    2829             : void
    2830           0 : keyedit_passwd (ctrl_t ctrl, const char *username)
    2831             : {
    2832             :   gpg_error_t err;
    2833             :   PKT_public_key *pk;
    2834           0 :   kbnode_t keyblock = NULL;
    2835             : 
    2836           0 :   pk = xtrycalloc (1, sizeof *pk);
    2837           0 :   if (!pk)
    2838             :     {
    2839           0 :       err = gpg_error_from_syserror ();
    2840           0 :       goto leave;
    2841             :     }
    2842           0 :   err = getkey_byname (ctrl, NULL, pk, username, 1, &keyblock);
    2843           0 :   if (err)
    2844           0 :     goto leave;
    2845             : 
    2846           0 :   err = change_passphrase (ctrl, keyblock);
    2847             : 
    2848             : leave:
    2849           0 :   release_kbnode (keyblock);
    2850           0 :   free_public_key (pk);
    2851           0 :   if (err)
    2852             :     {
    2853           0 :       log_info ("error changing the passphrase for '%s': %s\n",
    2854             :                 username, gpg_strerror (err));
    2855           0 :       write_status_error ("keyedit.passwd", err);
    2856             :     }
    2857             :   else
    2858           0 :     write_status_text (STATUS_SUCCESS, "keyedit.passwd");
    2859           0 : }
    2860             : 
    2861             : 
    2862             : /* Unattended adding of a new keyid.  USERNAME specifies the
    2863             :    key. NEWUID is the new user id to add to the key.  */
    2864             : void
    2865           1 : keyedit_quick_adduid (ctrl_t ctrl, const char *username, const char *newuid)
    2866             : {
    2867             :   gpg_error_t err;
    2868           1 :   KEYDB_HANDLE kdbhd = NULL;
    2869             :   KEYDB_SEARCH_DESC desc;
    2870           1 :   kbnode_t keyblock = NULL;
    2871             :   kbnode_t node;
    2872           1 :   char *uidstring = NULL;
    2873             : 
    2874           1 :   uidstring = xstrdup (newuid);
    2875           1 :   trim_spaces (uidstring);
    2876           1 :   if (!*uidstring)
    2877             :     {
    2878           0 :       log_error ("%s\n", gpg_strerror (GPG_ERR_INV_USER_ID));
    2879           0 :       goto leave;
    2880             :     }
    2881             : 
    2882             : #ifdef HAVE_W32_SYSTEM
    2883             :   /* See keyedit_menu for why we need this.  */
    2884             :   check_trustdb_stale (ctrl);
    2885             : #endif
    2886             : 
    2887             :   /* Search the key; we don't want the whole getkey stuff here.  */
    2888           1 :   kdbhd = keydb_new ();
    2889           1 :   if (!kdbhd)
    2890             :     {
    2891             :       /* Note that keydb_new has already used log_error.  */
    2892           0 :       goto leave;
    2893             :     }
    2894             : 
    2895           1 :   err = classify_user_id (username, &desc, 1);
    2896           1 :   if (!err)
    2897           1 :     err = keydb_search (kdbhd, &desc, 1, NULL);
    2898           1 :   if (!err)
    2899             :     {
    2900           1 :       err = keydb_get_keyblock (kdbhd, &keyblock);
    2901           1 :       if (err)
    2902             :         {
    2903           0 :           log_error (_("error reading keyblock: %s\n"), gpg_strerror (err));
    2904           0 :           goto leave;
    2905             :         }
    2906             :       /* Now with the keyblock retrieved, search again to detect an
    2907             :          ambiguous specification.  We need to save the found state so
    2908             :          that we can do an update later.  */
    2909           1 :       keydb_push_found_state (kdbhd);
    2910           1 :       err = keydb_search (kdbhd, &desc, 1, NULL);
    2911           1 :       if (!err)
    2912           0 :         err = gpg_error (GPG_ERR_AMBIGUOUS_NAME);
    2913           1 :       else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
    2914           1 :         err = 0;
    2915           1 :       keydb_pop_found_state (kdbhd);
    2916             : 
    2917           1 :       if (!err)
    2918             :         {
    2919             :           /* We require the secret primary key to add a UID.  */
    2920           1 :           node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
    2921           1 :           if (!node)
    2922           0 :             BUG ();
    2923           1 :           err = agent_probe_secret_key (ctrl, node->pkt->pkt.public_key);
    2924             :         }
    2925             :     }
    2926           1 :   if (err)
    2927             :     {
    2928           0 :       log_error (_("secret key \"%s\" not found: %s\n"),
    2929             :                  username, gpg_strerror (err));
    2930           0 :       goto leave;
    2931             :     }
    2932             : 
    2933           1 :   fix_keyblock (&keyblock);
    2934             : 
    2935           1 :   merge_keys_and_selfsig (keyblock);
    2936             : 
    2937           1 :   if (menu_adduid (ctrl, keyblock, 0, NULL, uidstring))
    2938             :     {
    2939           1 :       err = keydb_update_keyblock (ctrl, kdbhd, keyblock);
    2940           1 :       if (err)
    2941             :         {
    2942           0 :           log_error (_("update failed: %s\n"), gpg_strerror (err));
    2943           0 :           goto leave;
    2944             :         }
    2945             : 
    2946           1 :       if (update_trust)
    2947           0 :         revalidation_mark ();
    2948             :     }
    2949             : 
    2950             :  leave:
    2951           1 :   xfree (uidstring);
    2952           1 :   release_kbnode (keyblock);
    2953           1 :   keydb_release (kdbhd);
    2954           1 : }
    2955             : 
    2956             : /* Unattended revocation of a keyid.  USERNAME specifies the
    2957             :    key. UIDTOREV is the user id revoke from the key.  */
    2958             : void
    2959           1 : keyedit_quick_revuid (ctrl_t ctrl, const char *username, const char *uidtorev)
    2960             : {
    2961             :   gpg_error_t err;
    2962           1 :   KEYDB_HANDLE kdbhd = NULL;
    2963             :   KEYDB_SEARCH_DESC desc;
    2964           1 :   kbnode_t keyblock = NULL;
    2965             :   kbnode_t node;
    2966           1 :   int modified = 0;
    2967             :   size_t revlen;
    2968             : 
    2969             : #ifdef HAVE_W32_SYSTEM
    2970             :   /* See keyedit_menu for why we need this.  */
    2971             :   check_trustdb_stale (ctrl);
    2972             : #endif
    2973             : 
    2974             :   /* Search the key; we don't want the whole getkey stuff here.  */
    2975           1 :   kdbhd = keydb_new ();
    2976           1 :   if (!kdbhd)
    2977             :     {
    2978             :       /* Note that keydb_new has already used log_error.  */
    2979           0 :       goto leave;
    2980             :     }
    2981             : 
    2982           1 :   err = classify_user_id (username, &desc, 1);
    2983           1 :   if (!err)
    2984           1 :     err = keydb_search (kdbhd, &desc, 1, NULL);
    2985           1 :   if (!err)
    2986             :     {
    2987           1 :       err = keydb_get_keyblock (kdbhd, &keyblock);
    2988           1 :       if (err)
    2989             :         {
    2990           0 :           log_error (_("error reading keyblock: %s\n"), gpg_strerror (err));
    2991           0 :           goto leave;
    2992             :         }
    2993             :       /* Now with the keyblock retrieved, search again to detect an
    2994             :          ambiguous specification.  We need to save the found state so
    2995             :          that we can do an update later.  */
    2996           1 :       keydb_push_found_state (kdbhd);
    2997           1 :       err = keydb_search (kdbhd, &desc, 1, NULL);
    2998           1 :       if (!err)
    2999           0 :         err = gpg_error (GPG_ERR_AMBIGUOUS_NAME);
    3000           1 :       else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
    3001           1 :         err = 0;
    3002           1 :       keydb_pop_found_state (kdbhd);
    3003             : 
    3004           1 :       if (!err)
    3005             :         {
    3006             :           /* We require the secret primary key to revoke a UID.  */
    3007           1 :           node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
    3008           1 :           if (!node)
    3009           0 :             BUG ();
    3010           1 :           err = agent_probe_secret_key (ctrl, node->pkt->pkt.public_key);
    3011             :         }
    3012             :     }
    3013           1 :   if (err)
    3014             :     {
    3015           0 :       log_error (_("secret key \"%s\" not found: %s\n"),
    3016             :                  username, gpg_strerror (err));
    3017           0 :       goto leave;
    3018             :     }
    3019             : 
    3020           1 :   fix_keyblock (&keyblock);
    3021           1 :   setup_main_keyids (keyblock);
    3022             : 
    3023           1 :   revlen = strlen (uidtorev);
    3024             :   /* find the right UID */
    3025           2 :   for (node = keyblock; node; node = node->next)
    3026             :     {
    3027           2 :       if (node->pkt->pkttype == PKT_USER_ID
    3028           1 :           && revlen == node->pkt->pkt.user_id->len
    3029           1 :           && !memcmp (node->pkt->pkt.user_id->name, uidtorev, revlen))
    3030             :         {
    3031             :           struct revocation_reason_info *reason;
    3032             : 
    3033           1 :           reason = get_default_uid_revocation_reason ();
    3034           1 :           err = core_revuid (ctrl, keyblock, node, reason, &modified);
    3035           1 :           release_revocation_reason_info (reason);
    3036           1 :           if (err)
    3037             :             {
    3038           0 :               log_error (_("User ID revocation failed: %s\n"),
    3039             :                          gpg_strerror (err));
    3040           0 :               goto leave;
    3041             :             }
    3042           1 :           err = keydb_update_keyblock (ctrl, kdbhd, keyblock);
    3043           1 :           if (err)
    3044             :             {
    3045           0 :               log_error (_("update failed: %s\n"), gpg_strerror (err));
    3046           0 :               goto leave;
    3047             :             }
    3048             : 
    3049           1 :           if (update_trust)
    3050           1 :             revalidation_mark ();
    3051           1 :           goto leave;
    3052             :         }
    3053             :     }
    3054             : 
    3055             :  leave:
    3056           1 :   release_kbnode (keyblock);
    3057           1 :   keydb_release (kdbhd);
    3058           1 : }
    3059             : 
    3060             : 
    3061             : /* Find a keyblock by fingerprint because only this uniquely
    3062             :  * identifies a key and may thus be used to select a key for
    3063             :  * unattended subkey creation os key signing.  */
    3064             : static gpg_error_t
    3065           0 : find_by_primary_fpr (ctrl_t ctrl, const char *fpr,
    3066             :                      kbnode_t *r_keyblock, KEYDB_HANDLE *r_kdbhd)
    3067             : {
    3068             :   gpg_error_t err;
    3069           0 :   kbnode_t keyblock = NULL;
    3070           0 :   KEYDB_HANDLE kdbhd = NULL;
    3071             :   KEYDB_SEARCH_DESC desc;
    3072             :   byte fprbin[MAX_FINGERPRINT_LEN];
    3073             :   size_t fprlen;
    3074             : 
    3075           0 :   *r_keyblock = NULL;
    3076           0 :   *r_kdbhd = NULL;
    3077             : 
    3078           0 :   if (classify_user_id (fpr, &desc, 1)
    3079           0 :       || !(desc.mode == KEYDB_SEARCH_MODE_FPR
    3080           0 :            || desc.mode == KEYDB_SEARCH_MODE_FPR16
    3081           0 :            || desc.mode == KEYDB_SEARCH_MODE_FPR20))
    3082             :     {
    3083           0 :       log_error (_("\"%s\" is not a fingerprint\n"), fpr);
    3084           0 :       err = gpg_error (GPG_ERR_INV_NAME);
    3085           0 :       goto leave;
    3086             :     }
    3087           0 :   err = get_pubkey_byname (ctrl, NULL, NULL, fpr, &keyblock, &kdbhd, 1, 1);
    3088           0 :   if (err)
    3089             :     {
    3090           0 :       log_error (_("key \"%s\" not found: %s\n"), fpr, gpg_strerror (err));
    3091           0 :       goto leave;
    3092             :     }
    3093             : 
    3094             :   /* Check that the primary fingerprint has been given. */
    3095           0 :   fingerprint_from_pk (keyblock->pkt->pkt.public_key, fprbin, &fprlen);
    3096           0 :   if (fprlen == 16 && desc.mode == KEYDB_SEARCH_MODE_FPR16
    3097           0 :       && !memcmp (fprbin, desc.u.fpr, 16))
    3098             :     ;
    3099           0 :   else if (fprlen == 16 && desc.mode == KEYDB_SEARCH_MODE_FPR
    3100           0 :            && !memcmp (fprbin, desc.u.fpr, 16)
    3101           0 :            && !desc.u.fpr[16]
    3102           0 :            && !desc.u.fpr[17]
    3103           0 :            && !desc.u.fpr[18]
    3104           0 :            && !desc.u.fpr[19])
    3105             :     ;
    3106           0 :   else if (fprlen == 20 && (desc.mode == KEYDB_SEARCH_MODE_FPR20
    3107           0 :                             || desc.mode == KEYDB_SEARCH_MODE_FPR)
    3108           0 :            && !memcmp (fprbin, desc.u.fpr, 20))
    3109             :     ;
    3110             :   else
    3111             :     {
    3112           0 :       log_error (_("\"%s\" is not the primary fingerprint\n"), fpr);
    3113           0 :       err = gpg_error (GPG_ERR_INV_NAME);
    3114           0 :       goto leave;
    3115             :     }
    3116             : 
    3117           0 :   *r_keyblock = keyblock;
    3118           0 :   keyblock = NULL;
    3119           0 :   *r_kdbhd = kdbhd;
    3120           0 :   kdbhd = NULL;
    3121           0 :   err = 0;
    3122             : 
    3123             :  leave:
    3124           0 :   release_kbnode (keyblock);
    3125           0 :   keydb_release (kdbhd);
    3126           0 :   return err;
    3127             : }
    3128             : 
    3129             : 
    3130             : /* Unattended key signing function.  If the key specifified by FPR is
    3131             :    available and FPR is the primary fingerprint all user ids of the
    3132             :    key are signed using the default signing key.  If UIDS is an empty
    3133             :    list all usable UIDs are signed, if it is not empty, only those
    3134             :    user ids matching one of the entries of the list are signed.  With
    3135             :    LOCAL being true the signatures are marked as non-exportable.  */
    3136             : void
    3137           0 : keyedit_quick_sign (ctrl_t ctrl, const char *fpr, strlist_t uids,
    3138             :                     strlist_t locusr, int local)
    3139             : {
    3140             :   gpg_error_t err;
    3141           0 :   kbnode_t keyblock = NULL;
    3142           0 :   KEYDB_HANDLE kdbhd = NULL;
    3143           0 :   int modified = 0;
    3144             :   PKT_public_key *pk;
    3145             :   kbnode_t node;
    3146             :   strlist_t sl;
    3147             :   int any;
    3148             : 
    3149             : #ifdef HAVE_W32_SYSTEM
    3150             :   /* See keyedit_menu for why we need this.  */
    3151             :   check_trustdb_stale (ctrl);
    3152             : #endif
    3153             : 
    3154             :   /* We require a fingerprint because only this uniquely identifies a
    3155             :      key and may thus be used to select a key for unattended key
    3156             :      signing.  */
    3157           0 :   if (find_by_primary_fpr (ctrl, fpr, &keyblock, &kdbhd))
    3158           0 :     goto leave;
    3159             : 
    3160           0 :   if (fix_keyblock (&keyblock))
    3161           0 :     modified++;
    3162             : 
    3163             :   /* Give some info in verbose.  */
    3164           0 :   if (opt.verbose)
    3165             :     {
    3166           0 :       show_key_with_all_names (ctrl, es_stdout, keyblock, 0,
    3167             :                                1/*with_revoker*/, 1/*with_fingerprint*/,
    3168             :                                0, 0, 1);
    3169           0 :       es_fflush (es_stdout);
    3170             :     }
    3171             : 
    3172           0 :   pk = keyblock->pkt->pkt.public_key;
    3173           0 :   if (pk->flags.revoked)
    3174             :     {
    3175           0 :       if (!opt.verbose)
    3176           0 :         show_key_with_all_names (ctrl, es_stdout, keyblock, 0, 0, 0, 0, 0, 1);
    3177           0 :       log_error ("%s%s", _("Key is revoked."), _("  Unable to sign.\n"));
    3178           0 :       goto leave;
    3179             :     }
    3180             : 
    3181             :   /* Set the flags according to the UIDS list.  Fixme: We may want to
    3182             :      use classify_user_id along with dedicated compare functions so
    3183             :      that we match the same way as in the key lookup. */
    3184           0 :   any = 0;
    3185           0 :   menu_select_uid (keyblock, 0);   /* Better clear the flags first. */
    3186           0 :   for (sl=uids; sl; sl = sl->next)
    3187             :     {
    3188           0 :       const char *name = sl->d;
    3189           0 :       int count = 0;
    3190             : 
    3191           0 :       sl->flags &= ~(1|2);  /* Clear flags used for error reporting.  */
    3192             : 
    3193           0 :       for (node = keyblock; node; node = node->next)
    3194             :         {
    3195           0 :           if (node->pkt->pkttype == PKT_USER_ID)
    3196             :             {
    3197           0 :               PKT_user_id *uid = node->pkt->pkt.user_id;
    3198             : 
    3199           0 :               if (uid->attrib_data)
    3200             :                 ;
    3201           0 :               else if (*name == '='
    3202           0 :                        && strlen (name+1) == uid->len
    3203           0 :                        && !memcmp (uid->name, name + 1, uid->len))
    3204             :                 { /* Exact match - we don't do a check for ambiguity
    3205             :                    * in this case.  */
    3206           0 :                   node->flag |= NODFLG_SELUID;
    3207           0 :                   if (any != -1)
    3208             :                     {
    3209           0 :                       sl->flags |= 1;  /* Report as found.  */
    3210           0 :                       any = 1;
    3211             :                     }
    3212             :                 }
    3213           0 :               else if (ascii_memistr (uid->name, uid->len,
    3214           0 :                                       *name == '*'? name+1:name))
    3215             :                 {
    3216           0 :                   node->flag |= NODFLG_SELUID;
    3217           0 :                   if (any != -1)
    3218             :                     {
    3219           0 :                       sl->flags |= 1;  /* Report as found.  */
    3220           0 :                       any = 1;
    3221             :                     }
    3222           0 :                   count++;
    3223             :                 }
    3224             :             }
    3225             :         }
    3226             : 
    3227           0 :       if (count > 1)
    3228             :         {
    3229           0 :           any = -1;        /* Force failure at end.  */
    3230           0 :           sl->flags |= 2;  /* Report as ambiguous.  */
    3231             :         }
    3232             :     }
    3233             : 
    3234             :   /* Check whether all given user ids were found.  */
    3235           0 :   for (sl=uids; sl; sl = sl->next)
    3236           0 :     if (!(sl->flags & 1))
    3237           0 :       any = -1;  /* That user id was not found.  */
    3238             : 
    3239             :   /* Print an error if there was a problem with the user ids.  */
    3240           0 :   if (uids && any < 1)
    3241             :     {
    3242           0 :       if (!opt.verbose)
    3243           0 :         show_key_with_all_names (ctrl, es_stdout, keyblock, 0, 0, 0, 0, 0, 1);
    3244           0 :       es_fflush (es_stdout);
    3245           0 :       for (sl=uids; sl; sl = sl->next)
    3246             :         {
    3247           0 :           if ((sl->flags & 2))
    3248           0 :             log_info (_("Invalid user ID '%s': %s\n"),
    3249           0 :                       sl->d, gpg_strerror (GPG_ERR_AMBIGUOUS_NAME));
    3250           0 :           else if (!(sl->flags & 1))
    3251           0 :             log_info (_("Invalid user ID '%s': %s\n"),
    3252           0 :                       sl->d, gpg_strerror (GPG_ERR_NOT_FOUND));
    3253             :         }
    3254           0 :       log_error ("%s  %s", _("No matching user IDs."), _("Nothing to sign.\n"));
    3255           0 :       goto leave;
    3256             :     }
    3257             : 
    3258             :   /* Sign. */
    3259           0 :   sign_uids (ctrl, es_stdout, keyblock, locusr, &modified, local, 0, 0, 0, 1);
    3260           0 :   es_fflush (es_stdout);
    3261             : 
    3262           0 :   if (modified)
    3263             :     {
    3264           0 :       err = keydb_update_keyblock (ctrl, kdbhd, keyblock);
    3265           0 :       if (err)
    3266             :         {
    3267           0 :           log_error (_("update failed: %s\n"), gpg_strerror (err));
    3268           0 :           goto leave;
    3269             :         }
    3270             :     }
    3271             :   else
    3272           0 :     log_info (_("Key not changed so no update needed.\n"));
    3273             : 
    3274           0 :   if (update_trust)
    3275           0 :     revalidation_mark ();
    3276             : 
    3277             : 
    3278             :  leave:
    3279           0 :   release_kbnode (keyblock);
    3280           0 :   keydb_release (kdbhd);
    3281           0 : }
    3282             : 
    3283             : 
    3284             : /* Unattended subkey creation function.
    3285             :  *
    3286             :  */
    3287             : void
    3288           0 : keyedit_quick_addkey (ctrl_t ctrl, const char *fpr, const char *algostr,
    3289             :                       const char *usagestr, const char *expirestr)
    3290             : {
    3291             :   gpg_error_t err;
    3292             :   kbnode_t keyblock;
    3293             :   KEYDB_HANDLE kdbhd;
    3294           0 :   int modified = 0;
    3295             :   PKT_public_key *pk;
    3296             : 
    3297             : #ifdef HAVE_W32_SYSTEM
    3298             :   /* See keyedit_menu for why we need this.  */
    3299             :   check_trustdb_stale (ctrl);
    3300             : #endif
    3301             : 
    3302             :   /* We require a fingerprint because only this uniquely identifies a
    3303             :    * key and may thus be used to select a key for unattended subkey
    3304             :    * creation.  */
    3305           0 :   if (find_by_primary_fpr (ctrl, fpr, &keyblock, &kdbhd))
    3306           0 :     goto leave;
    3307             : 
    3308           0 :   if (fix_keyblock (&keyblock))
    3309           0 :     modified++;
    3310             : 
    3311           0 :   pk = keyblock->pkt->pkt.public_key;
    3312           0 :   if (pk->flags.revoked)
    3313             :     {
    3314           0 :       if (!opt.verbose)
    3315           0 :         show_key_with_all_names (ctrl, es_stdout, keyblock, 0, 0, 0, 0, 0, 1);
    3316           0 :       log_error ("%s%s", _("Key is revoked."), "\n");
    3317           0 :       goto leave;
    3318             :     }
    3319             : 
    3320             :   /* Create the subkey.  Note that the called function already prints
    3321             :    * an error message. */
    3322           0 :   if (!generate_subkeypair (ctrl, keyblock, algostr, usagestr, expirestr))
    3323           0 :     modified = 1;
    3324           0 :   es_fflush (es_stdout);
    3325             : 
    3326             :   /* Store.  */
    3327           0 :   if (modified)
    3328             :     {
    3329           0 :       err = keydb_update_keyblock (ctrl, kdbhd, keyblock);
    3330           0 :       if (err)
    3331             :         {
    3332           0 :           log_error (_("update failed: %s\n"), gpg_strerror (err));
    3333           0 :           goto leave;
    3334             :         }
    3335             :     }
    3336             :   else
    3337           0 :     log_info (_("Key not changed so no update needed.\n"));
    3338             : 
    3339             :  leave:
    3340           0 :   release_kbnode (keyblock);
    3341           0 :   keydb_release (kdbhd);
    3342           0 : }
    3343             : 
    3344             : 
    3345             : 
    3346             : static void
    3347           0 : tty_print_notations (int indent, PKT_signature * sig)
    3348             : {
    3349           0 :   int first = 1;
    3350             :   struct notation *notation, *nd;
    3351             : 
    3352           0 :   if (indent < 0)
    3353             :     {
    3354           0 :       first = 0;
    3355           0 :       indent = -indent;
    3356             :     }
    3357             : 
    3358           0 :   notation = sig_to_notation (sig);
    3359             : 
    3360           0 :   for (nd = notation; nd; nd = nd->next)
    3361             :     {
    3362           0 :       if (!first)
    3363           0 :         tty_printf ("%*s", indent, "");
    3364             :       else
    3365           0 :         first = 0;
    3366             : 
    3367           0 :       tty_print_utf8_string (nd->name, strlen (nd->name));
    3368           0 :       tty_printf ("=");
    3369           0 :       tty_print_utf8_string (nd->value, strlen (nd->value));
    3370           0 :       tty_printf ("\n");
    3371             :     }
    3372             : 
    3373           0 :   free_notation (notation);
    3374           0 : }
    3375             : 
    3376             : 
    3377             : /*
    3378             :  * Show preferences of a public keyblock.
    3379             :  */
    3380             : static void
    3381           0 : show_prefs (PKT_user_id * uid, PKT_signature * selfsig, int verbose)
    3382             : {
    3383           0 :   const prefitem_t fake = { 0, 0 };
    3384             :   const prefitem_t *prefs;
    3385             :   int i;
    3386             : 
    3387           0 :   if (!uid)
    3388           0 :     return;
    3389             : 
    3390           0 :   if (uid->prefs)
    3391           0 :     prefs = uid->prefs;
    3392           0 :   else if (verbose)
    3393           0 :     prefs = &fake;
    3394             :   else
    3395           0 :     return;
    3396             : 
    3397           0 :   if (verbose)
    3398             :     {
    3399           0 :       int any, des_seen = 0, sha1_seen = 0, uncomp_seen = 0;
    3400             : 
    3401           0 :       tty_printf ("     ");
    3402           0 :       tty_printf (_("Cipher: "));
    3403           0 :       for (i = any = 0; prefs[i].type; i++)
    3404             :         {
    3405           0 :           if (prefs[i].type == PREFTYPE_SYM)
    3406             :             {
    3407           0 :               if (any)
    3408           0 :                 tty_printf (", ");
    3409           0 :               any = 1;
    3410             :               /* We don't want to display strings for experimental algos */
    3411           0 :               if (!openpgp_cipher_test_algo (prefs[i].value)
    3412           0 :                   && prefs[i].value < 100)
    3413           0 :                 tty_printf ("%s", openpgp_cipher_algo_name (prefs[i].value));
    3414             :               else
    3415           0 :                 tty_printf ("[%d]", prefs[i].value);
    3416           0 :               if (prefs[i].value == CIPHER_ALGO_3DES)
    3417           0 :                 des_seen = 1;
    3418             :             }
    3419             :         }
    3420           0 :       if (!des_seen)
    3421             :         {
    3422           0 :           if (any)
    3423           0 :             tty_printf (", ");
    3424           0 :           tty_printf ("%s", openpgp_cipher_algo_name (CIPHER_ALGO_3DES));
    3425             :         }
    3426           0 :       tty_printf ("\n     ");
    3427           0 :       tty_printf (_("Digest: "));
    3428           0 :       for (i = any = 0; prefs[i].type; i++)
    3429             :         {
    3430           0 :           if (prefs[i].type == PREFTYPE_HASH)
    3431             :             {
    3432           0 :               if (any)
    3433           0 :                 tty_printf (", ");
    3434           0 :               any = 1;
    3435             :               /* We don't want to display strings for experimental algos */
    3436           0 :               if (!gcry_md_test_algo (prefs[i].value) && prefs[i].value < 100)
    3437           0 :                 tty_printf ("%s", gcry_md_algo_name (prefs[i].value));
    3438             :               else
    3439           0 :                 tty_printf ("[%d]", prefs[i].value);
    3440           0 :               if (prefs[i].value == DIGEST_ALGO_SHA1)
    3441           0 :                 sha1_seen = 1;
    3442             :             }
    3443             :         }
    3444           0 :       if (!sha1_seen)
    3445             :         {
    3446           0 :           if (any)
    3447           0 :             tty_printf (", ");
    3448           0 :           tty_printf ("%s", gcry_md_algo_name (DIGEST_ALGO_SHA1));
    3449             :         }
    3450           0 :       tty_printf ("\n     ");
    3451           0 :       tty_printf (_("Compression: "));
    3452           0 :       for (i = any = 0; prefs[i].type; i++)
    3453             :         {
    3454           0 :           if (prefs[i].type == PREFTYPE_ZIP)
    3455             :             {
    3456           0 :               const char *s = compress_algo_to_string (prefs[i].value);
    3457             : 
    3458           0 :               if (any)
    3459           0 :                 tty_printf (", ");
    3460           0 :               any = 1;
    3461             :               /* We don't want to display strings for experimental algos */
    3462           0 :               if (s && prefs[i].value < 100)
    3463           0 :                 tty_printf ("%s", s);
    3464             :               else
    3465           0 :                 tty_printf ("[%d]", prefs[i].value);
    3466           0 :               if (prefs[i].value == COMPRESS_ALGO_NONE)
    3467           0 :                 uncomp_seen = 1;
    3468             :             }
    3469             :         }
    3470           0 :       if (!uncomp_seen)
    3471             :         {
    3472           0 :           if (any)
    3473           0 :             tty_printf (", ");
    3474             :           else
    3475             :             {
    3476           0 :               tty_printf ("%s", compress_algo_to_string (COMPRESS_ALGO_ZIP));
    3477           0 :               tty_printf (", ");
    3478             :             }
    3479           0 :           tty_printf ("%s", compress_algo_to_string (COMPRESS_ALGO_NONE));
    3480             :         }
    3481           0 :       if (uid->flags.mdc || !uid->flags.ks_modify)
    3482             :         {
    3483           0 :           tty_printf ("\n     ");
    3484           0 :           tty_printf (_("Features: "));
    3485           0 :           any = 0;
    3486           0 :           if (uid->flags.mdc)
    3487             :             {
    3488           0 :               tty_printf ("MDC");
    3489           0 :               any = 1;
    3490             :             }
    3491           0 :           if (!uid->flags.ks_modify)
    3492             :             {
    3493           0 :               if (any)
    3494           0 :                 tty_printf (", ");
    3495           0 :               tty_printf (_("Keyserver no-modify"));
    3496             :             }
    3497             :         }
    3498           0 :       tty_printf ("\n");
    3499             : 
    3500           0 :       if (selfsig)
    3501             :         {
    3502             :           const byte *pref_ks;
    3503             :           size_t pref_ks_len;
    3504             : 
    3505           0 :           pref_ks = parse_sig_subpkt (selfsig->hashed,
    3506             :                                       SIGSUBPKT_PREF_KS, &pref_ks_len);
    3507           0 :           if (pref_ks && pref_ks_len)
    3508             :             {
    3509           0 :               tty_printf ("     ");
    3510           0 :               tty_printf (_("Preferred keyserver: "));
    3511           0 :               tty_print_utf8_string (pref_ks, pref_ks_len);
    3512           0 :               tty_printf ("\n");
    3513             :             }
    3514             : 
    3515           0 :           if (selfsig->flags.notation)
    3516             :             {
    3517           0 :               tty_printf ("     ");
    3518           0 :               tty_printf (_("Notations: "));
    3519           0 :               tty_print_notations (5 + strlen (_("Notations: ")), selfsig);
    3520             :             }
    3521             :         }
    3522             :     }
    3523             :   else
    3524             :     {
    3525           0 :       tty_printf ("    ");
    3526           0 :       for (i = 0; prefs[i].type; i++)
    3527             :         {
    3528           0 :           tty_printf (" %c%d", prefs[i].type == PREFTYPE_SYM ? 'S' :
    3529           0 :                       prefs[i].type == PREFTYPE_HASH ? 'H' :
    3530           0 :                       prefs[i].type == PREFTYPE_ZIP ? 'Z' : '?',
    3531           0 :                       prefs[i].value);
    3532             :         }
    3533           0 :       if (uid->flags.mdc)
    3534           0 :         tty_printf (" [mdc]");
    3535           0 :       if (!uid->flags.ks_modify)
    3536           0 :         tty_printf (" [no-ks-modify]");
    3537           0 :       tty_printf ("\n");
    3538             :     }
    3539             : }
    3540             : 
    3541             : 
    3542             : /* This is the version of show_key_with_all_names used when
    3543             :    opt.with_colons is used.  It prints all available data in a easy to
    3544             :    parse format and does not translate utf8 */
    3545             : static void
    3546           0 : show_key_with_all_names_colon (ctrl_t ctrl, estream_t fp, kbnode_t keyblock)
    3547             : {
    3548             :   KBNODE node;
    3549           0 :   int i, j, ulti_hack = 0;
    3550           0 :   byte pk_version = 0;
    3551           0 :   PKT_public_key *primary = NULL;
    3552             :   int have_seckey;
    3553             : 
    3554           0 :   if (!fp)
    3555           0 :     fp = es_stdout;
    3556             : 
    3557             :   /* the keys */
    3558           0 :   for (node = keyblock; node; node = node->next)
    3559             :     {
    3560           0 :       if (node->pkt->pkttype == PKT_PUBLIC_KEY
    3561           0 :           || (node->pkt->pkttype == PKT_PUBLIC_SUBKEY))
    3562             :         {
    3563           0 :           PKT_public_key *pk = node->pkt->pkt.public_key;
    3564             :           u32 keyid[2];
    3565             : 
    3566           0 :           if (node->pkt->pkttype == PKT_PUBLIC_KEY)
    3567             :             {
    3568           0 :               pk_version = pk->version;
    3569           0 :               primary = pk;
    3570             :             }
    3571             : 
    3572           0 :           keyid_from_pk (pk, keyid);
    3573           0 :           have_seckey = !agent_probe_secret_key (ctrl, pk);
    3574             : 
    3575           0 :           if (node->pkt->pkttype == PKT_PUBLIC_KEY)
    3576           0 :             es_fputs (have_seckey? "sec:" : "pub:", fp);
    3577             :           else
    3578           0 :             es_fputs (have_seckey? "ssb:" : "sub:", fp);
    3579             : 
    3580           0 :           if (!pk->flags.valid)
    3581           0 :             es_putc ('i', fp);
    3582           0 :           else if (pk->flags.revoked)
    3583           0 :             es_putc ('r', fp);
    3584           0 :           else if (pk->has_expired)
    3585           0 :             es_putc ('e', fp);
    3586           0 :           else if (!(opt.fast_list_mode || opt.no_expensive_trust_checks))
    3587             :             {
    3588           0 :               int trust = get_validity_info (ctrl, keyblock, pk, NULL);
    3589           0 :               if (trust == 'u')
    3590           0 :                 ulti_hack = 1;
    3591           0 :               es_putc (trust, fp);
    3592             :             }
    3593             : 
    3594           0 :           es_fprintf (fp, ":%u:%d:%08lX%08lX:%lu:%lu::",
    3595             :                       nbits_from_pk (pk),
    3596           0 :                       pk->pubkey_algo,
    3597           0 :                       (ulong) keyid[0], (ulong) keyid[1],
    3598           0 :                       (ulong) pk->timestamp, (ulong) pk->expiredate);
    3599           0 :           if (node->pkt->pkttype == PKT_PUBLIC_KEY
    3600           0 :               && !(opt.fast_list_mode || opt.no_expensive_trust_checks))
    3601           0 :             es_putc (get_ownertrust_info (pk), fp);
    3602           0 :           es_putc (':', fp);
    3603           0 :           es_putc (':', fp);
    3604           0 :           es_putc (':', fp);
    3605             :           /* Print capabilities.  */
    3606           0 :           if ((pk->pubkey_usage & PUBKEY_USAGE_ENC))
    3607           0 :             es_putc ('e', fp);
    3608           0 :           if ((pk->pubkey_usage & PUBKEY_USAGE_SIG))
    3609           0 :             es_putc ('s', fp);
    3610           0 :           if ((pk->pubkey_usage & PUBKEY_USAGE_CERT))
    3611           0 :             es_putc ('c', fp);
    3612           0 :           if ((pk->pubkey_usage & PUBKEY_USAGE_AUTH))
    3613           0 :             es_putc ('a', fp);
    3614           0 :           es_putc ('\n', fp);
    3615             : 
    3616           0 :           print_fingerprint (fp, pk, 0);
    3617           0 :           print_revokers (fp, pk);
    3618             :         }
    3619             :     }
    3620             : 
    3621             :   /* the user ids */
    3622           0 :   i = 0;
    3623           0 :   for (node = keyblock; node; node = node->next)
    3624             :     {
    3625           0 :       if (node->pkt->pkttype == PKT_USER_ID)
    3626             :         {
    3627           0 :           PKT_user_id *uid = node->pkt->pkt.user_id;
    3628             : 
    3629           0 :           ++i;
    3630             : 
    3631           0 :           if (uid->attrib_data)
    3632           0 :             es_fputs ("uat:", fp);
    3633             :           else
    3634           0 :             es_fputs ("uid:", fp);
    3635             : 
    3636           0 :           if (uid->is_revoked)
    3637           0 :             es_fputs ("r::::::::", fp);
    3638           0 :           else if (uid->is_expired)
    3639           0 :             es_fputs ("e::::::::", fp);
    3640           0 :           else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
    3641           0 :             es_fputs ("::::::::", fp);
    3642             :           else
    3643             :             {
    3644             :               int uid_validity;
    3645             : 
    3646           0 :               if (primary && !ulti_hack)
    3647           0 :                 uid_validity = get_validity_info (ctrl, keyblock, primary, uid);
    3648             :               else
    3649           0 :                 uid_validity = 'u';
    3650           0 :               es_fprintf (fp, "%c::::::::", uid_validity);
    3651             :             }
    3652             : 
    3653           0 :           if (uid->attrib_data)
    3654           0 :             es_fprintf (fp, "%u %lu", uid->numattribs, uid->attrib_len);
    3655             :           else
    3656           0 :             es_write_sanitized (fp, uid->name, uid->len, ":", NULL);
    3657             : 
    3658           0 :           es_putc (':', fp);
    3659             :           /* signature class */
    3660           0 :           es_putc (':', fp);
    3661             :           /* capabilities */
    3662           0 :           es_putc (':', fp);
    3663             :           /* preferences */
    3664           0 :           if (pk_version > 3 || uid->selfsigversion > 3)
    3665             :             {
    3666           0 :               const prefitem_t *prefs = uid->prefs;
    3667             : 
    3668           0 :               for (j = 0; prefs && prefs[j].type; j++)
    3669             :                 {
    3670           0 :                   if (j)
    3671           0 :                     es_putc (' ', fp);
    3672           0 :                   es_fprintf (fp,
    3673           0 :                               "%c%d", prefs[j].type == PREFTYPE_SYM ? 'S' :
    3674           0 :                               prefs[j].type == PREFTYPE_HASH ? 'H' :
    3675           0 :                               prefs[j].type == PREFTYPE_ZIP ? 'Z' : '?',
    3676           0 :                               prefs[j].value);
    3677             :                 }
    3678           0 :               if (uid->flags.mdc)
    3679           0 :                 es_fputs (",mdc", fp);
    3680           0 :               if (!uid->flags.ks_modify)
    3681           0 :                 es_fputs (",no-ks-modify", fp);
    3682             :             }
    3683           0 :           es_putc (':', fp);
    3684             :           /* flags */
    3685           0 :           es_fprintf (fp, "%d,", i);
    3686           0 :           if (uid->is_primary)
    3687           0 :             es_putc ('p', fp);
    3688           0 :           if (uid->is_revoked)
    3689           0 :             es_putc ('r', fp);
    3690           0 :           if (uid->is_expired)
    3691           0 :             es_putc ('e', fp);
    3692           0 :           if ((node->flag & NODFLG_SELUID))
    3693           0 :             es_putc ('s', fp);
    3694           0 :           if ((node->flag & NODFLG_MARK_A))
    3695           0 :             es_putc ('m', fp);
    3696           0 :           es_putc (':', fp);
    3697           0 :           if (opt.trust_model == TM_TOFU || opt.trust_model == TM_TOFU_PGP)
    3698             :             {
    3699             : #ifdef USE_TOFU
    3700             :               enum tofu_policy policy;
    3701           0 :               if (! tofu_get_policy (ctrl, primary, uid, &policy)
    3702           0 :                   && policy != TOFU_POLICY_NONE)
    3703           0 :                 es_fprintf (fp, "%s", tofu_policy_str (policy));
    3704             : #endif /*USE_TOFU*/
    3705             :             }
    3706           0 :           es_putc (':', fp);
    3707           0 :           es_putc ('\n', fp);
    3708             :         }
    3709             :     }
    3710           0 : }
    3711             : 
    3712             : 
    3713             : static void
    3714           0 : show_names (ctrl_t ctrl, estream_t fp,
    3715             :             kbnode_t keyblock, PKT_public_key * pk, unsigned int flag,
    3716             :             int with_prefs)
    3717             : {
    3718             :   KBNODE node;
    3719           0 :   int i = 0;
    3720             : 
    3721           0 :   for (node = keyblock; node; node = node->next)
    3722             :     {
    3723           0 :       if (node->pkt->pkttype == PKT_USER_ID && !is_deleted_kbnode (node))
    3724             :         {
    3725           0 :           PKT_user_id *uid = node->pkt->pkt.user_id;
    3726           0 :           ++i;
    3727           0 :           if (!flag || (flag && (node->flag & flag)))
    3728             :             {
    3729           0 :               if (!(flag & NODFLG_MARK_A) && pk)
    3730           0 :                 tty_fprintf (fp, "%s ", uid_trust_string_fixed (ctrl, pk, uid));
    3731             : 
    3732           0 :               if (flag & NODFLG_MARK_A)
    3733           0 :                 tty_fprintf (fp, "     ");
    3734           0 :               else if (node->flag & NODFLG_SELUID)
    3735           0 :                 tty_fprintf (fp, "(%d)* ", i);
    3736           0 :               else if (uid->is_primary)
    3737           0 :                 tty_fprintf (fp, "(%d). ", i);
    3738             :               else
    3739           0 :                 tty_fprintf (fp, "(%d)  ", i);
    3740           0 :               tty_print_utf8_string2 (fp, uid->name, uid->len, 0);
    3741           0 :               tty_fprintf (fp, "\n");
    3742           0 :               if (with_prefs && pk)
    3743             :                 {
    3744           0 :                   if (pk->version > 3 || uid->selfsigversion > 3)
    3745           0 :                     {
    3746           0 :                       PKT_signature *selfsig = NULL;
    3747             :                       KBNODE signode;
    3748             : 
    3749           0 :                       for (signode = node->next;
    3750           0 :                            signode && signode->pkt->pkttype == PKT_SIGNATURE;
    3751           0 :                            signode = signode->next)
    3752             :                         {
    3753           0 :                           if (signode->pkt->pkt.signature->
    3754             :                               flags.chosen_selfsig)
    3755             :                             {
    3756           0 :                               selfsig = signode->pkt->pkt.signature;
    3757           0 :                               break;
    3758             :                             }
    3759             :                         }
    3760             : 
    3761           0 :                       show_prefs (uid, selfsig, with_prefs == 2);
    3762             :                     }
    3763             :                   else
    3764           0 :                     tty_fprintf (fp, _("There are no preferences on a"
    3765             :                                        " PGP 2.x-style user ID.\n"));
    3766             :                 }
    3767             :             }
    3768             :         }
    3769             :     }
    3770           0 : }
    3771             : 
    3772             : 
    3773             : /*
    3774             :  * Display the key a the user ids, if only_marked is true, do only so
    3775             :  * for user ids with mark A flag set and do not display the index
    3776             :  * number.  If FP is not NULL print to the given stream and not to the
    3777             :  * tty (ignored in with-colons mode).
    3778             :  */
    3779             : static void
    3780           0 : show_key_with_all_names (ctrl_t ctrl, estream_t fp,
    3781             :                          KBNODE keyblock, int only_marked, int with_revoker,
    3782             :                          int with_fpr, int with_subkeys, int with_prefs,
    3783             :                          int nowarn)
    3784             : {
    3785             :   gpg_error_t err;
    3786             :   kbnode_t node;
    3787             :   int i;
    3788           0 :   int do_warn = 0;
    3789           0 :   int have_seckey = 0;
    3790           0 :   char *serialno = NULL;
    3791           0 :   PKT_public_key *primary = NULL;
    3792             :   char pkstrbuf[PUBKEY_STRING_SIZE];
    3793             : 
    3794           0 :   if (opt.with_colons)
    3795             :     {
    3796           0 :       show_key_with_all_names_colon (ctrl, fp, keyblock);
    3797           0 :       return;
    3798             :     }
    3799             : 
    3800             :   /* the keys */
    3801           0 :   for (node = keyblock; node; node = node->next)
    3802             :     {
    3803           0 :       if (node->pkt->pkttype == PKT_PUBLIC_KEY
    3804           0 :           || (with_subkeys && node->pkt->pkttype == PKT_PUBLIC_SUBKEY
    3805           0 :               && !is_deleted_kbnode (node)))
    3806             :         {
    3807           0 :           PKT_public_key *pk = node->pkt->pkt.public_key;
    3808           0 :           const char *otrust = "err";
    3809           0 :           const char *trust = "err";
    3810             : 
    3811           0 :           if (node->pkt->pkttype == PKT_PUBLIC_KEY)
    3812             :             {
    3813             :               /* do it here, so that debug messages don't clutter the
    3814             :                * output */
    3815             :               static int did_warn = 0;
    3816             : 
    3817           0 :               trust = get_validity_string (ctrl, pk, NULL);
    3818           0 :               otrust = get_ownertrust_string (pk);
    3819             : 
    3820             :               /* Show a warning once */
    3821           0 :               if (!did_warn
    3822           0 :                   && (get_validity (ctrl, keyblock, pk, NULL, NULL, 0)
    3823           0 :                       & TRUST_FLAG_PENDING_CHECK))
    3824             :                 {
    3825           0 :                   did_warn = 1;
    3826           0 :                   do_warn = 1;
    3827             :                 }
    3828             : 
    3829           0 :               primary = pk;
    3830             :             }
    3831             : 
    3832           0 :           if (pk->flags.revoked)
    3833             :             {
    3834           0 :               char *user = get_user_id_string_native (pk->revoked.keyid);
    3835           0 :               tty_fprintf (fp,
    3836           0 :                            _("The following key was revoked on"
    3837             :                             " %s by %s key %s\n"),
    3838             :                           revokestr_from_pk (pk),
    3839           0 :                           gcry_pk_algo_name (pk->revoked.algo), user);
    3840           0 :               xfree (user);
    3841             :             }
    3842             : 
    3843           0 :           if (with_revoker)
    3844             :             {
    3845           0 :               if (!pk->revkey && pk->numrevkeys)
    3846           0 :                 BUG ();
    3847             :               else
    3848           0 :                 for (i = 0; i < pk->numrevkeys; i++)
    3849             :                   {
    3850             :                     u32 r_keyid[2];
    3851             :                     char *user;
    3852             :                     const char *algo;
    3853             : 
    3854           0 :                     algo = gcry_pk_algo_name (pk->revkey[i].algid);
    3855           0 :                     keyid_from_fingerprint (pk->revkey[i].fpr,
    3856             :                                             MAX_FINGERPRINT_LEN, r_keyid);
    3857             : 
    3858           0 :                     user = get_user_id_string_native (r_keyid);
    3859           0 :                     tty_fprintf (fp,
    3860           0 :                                  _("This key may be revoked by %s key %s"),
    3861             :                                  algo ? algo : "?", user);
    3862             : 
    3863           0 :                     if (pk->revkey[i].class & 0x40)
    3864             :                       {
    3865           0 :                         tty_fprintf (fp, " ");
    3866           0 :                         tty_fprintf (fp, _("(sensitive)"));
    3867             :                       }
    3868             : 
    3869           0 :                     tty_fprintf (fp, "\n");
    3870           0 :                     xfree (user);
    3871             :                   }
    3872             :             }
    3873             : 
    3874           0 :           keyid_from_pk (pk, NULL);
    3875             : 
    3876           0 :           xfree (serialno);
    3877           0 :           serialno = NULL;
    3878             :           {
    3879             :             char *hexgrip;
    3880             : 
    3881           0 :             err = hexkeygrip_from_pk (pk, &hexgrip);
    3882           0 :             if (err)
    3883             :               {
    3884           0 :                 log_error ("error computing a keygrip: %s\n",
    3885             :                            gpg_strerror (err));
    3886           0 :                 have_seckey = 0;
    3887             :               }
    3888             :             else
    3889           0 :               have_seckey = !agent_get_keyinfo (ctrl, hexgrip, &serialno, NULL);
    3890           0 :             xfree (hexgrip);
    3891             :           }
    3892             : 
    3893           0 :           tty_fprintf
    3894             :             (fp, "%s%c %s/%s",
    3895           0 :              node->pkt->pkttype == PKT_PUBLIC_KEY && have_seckey? "sec" :
    3896           0 :              node->pkt->pkttype == PKT_PUBLIC_KEY ?               "pub" :
    3897           0 :              have_seckey ?                                        "ssb" :
    3898             :                                                                   "sub",
    3899           0 :              (node->flag & NODFLG_SELKEY) ? '*' : ' ',
    3900             :              pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
    3901           0 :              keystr (pk->keyid));
    3902             : 
    3903           0 :           if (opt.legacy_list_mode)
    3904           0 :             tty_fprintf (fp, "  ");
    3905             :           else
    3906           0 :             tty_fprintf (fp, "\n     ");
    3907             : 
    3908           0 :           tty_fprintf (fp, _("created: %s"), datestr_from_pk (pk));
    3909           0 :           tty_fprintf (fp, "  ");
    3910           0 :           if (pk->flags.revoked)
    3911           0 :             tty_fprintf (fp, _("revoked: %s"), revokestr_from_pk (pk));
    3912           0 :           else if (pk->has_expired)
    3913           0 :             tty_fprintf (fp, _("expired: %s"), expirestr_from_pk (pk));
    3914             :           else
    3915           0 :             tty_fprintf (fp, _("expires: %s"), expirestr_from_pk (pk));
    3916           0 :           tty_fprintf (fp, "  ");
    3917           0 :           tty_fprintf (fp, _("usage: %s"), usagestr_from_pk (pk, 1));
    3918           0 :           tty_fprintf (fp, "\n");
    3919             : 
    3920           0 :           if (serialno)
    3921             :             {
    3922             :               /* The agent told us that a secret key is available and
    3923             :                  that it has been stored on a card.  */
    3924           0 :               tty_fprintf (fp, "%*s%s", opt.legacy_list_mode? 21:5, "",
    3925             :                            _("card-no: "));
    3926           0 :               if (strlen (serialno) == 32
    3927           0 :                   && !strncmp (serialno, "D27600012401", 12))
    3928             :                 {
    3929             :                   /* This is an OpenPGP card.  Print the relevant part.  */
    3930             :                   /* Example: D2760001240101010001000003470000 */
    3931             :                   /*                          xxxxyyyyyyyy     */
    3932           0 :                   tty_fprintf (fp, "%.*s %.*s\n",
    3933             :                                4, serialno+16, 8, serialno+20);
    3934             :                 }
    3935             :               else
    3936           0 :                 tty_fprintf (fp, "%s\n", serialno);
    3937             : 
    3938             :             }
    3939           0 :           else if (pk->seckey_info
    3940           0 :               && pk->seckey_info->is_protected
    3941           0 :               && pk->seckey_info->s2k.mode == 1002)
    3942             :             {
    3943             :               /* FIXME: Check wether this code path is still used.  */
    3944           0 :               tty_fprintf (fp, "%*s%s", opt.legacy_list_mode? 21:5, "",
    3945             :                            _("card-no: "));
    3946           0 :               if (pk->seckey_info->ivlen == 16
    3947           0 :                   && !memcmp (pk->seckey_info->iv,
    3948             :                               "\xD2\x76\x00\x01\x24\x01", 6))
    3949             :                 {
    3950             :                   /* This is an OpenPGP card. */
    3951           0 :                   for (i = 8; i < 14; i++)
    3952             :                     {
    3953           0 :                       if (i == 10)
    3954           0 :                         tty_fprintf (fp, " ");
    3955           0 :                       tty_fprintf (fp, "%02X", pk->seckey_info->iv[i]);
    3956             :                     }
    3957             :                 }
    3958             :               else
    3959             :                 {
    3960             :                   /* Unknown card: Print all. */
    3961           0 :                   for (i = 0; i < pk->seckey_info->ivlen; i++)
    3962           0 :                     tty_fprintf (fp, "%02X", pk->seckey_info->iv[i]);
    3963             :                 }
    3964           0 :               tty_fprintf (fp, "\n");
    3965             :             }
    3966             : 
    3967           0 :           if (node->pkt->pkttype == PKT_PUBLIC_KEY
    3968           0 :               || node->pkt->pkttype == PKT_SECRET_KEY)
    3969             :             {
    3970           0 :               if (opt.trust_model != TM_ALWAYS)
    3971             :                 {
    3972           0 :                   tty_fprintf (fp, "%*s",
    3973           0 :                                opt.legacy_list_mode?
    3974           0 :                                ((int) keystrlen () + 13):5, "");
    3975             :                   /* Ownertrust is only meaningful for the PGP or
    3976             :                      classic trust models, or PGP combined with TOFU */
    3977           0 :                   if (opt.trust_model == TM_PGP
    3978           0 :                       || opt.trust_model == TM_CLASSIC
    3979           0 :                       || opt.trust_model == TM_TOFU_PGP)
    3980             :                     {
    3981           0 :                       int width = 14 - strlen (otrust);
    3982           0 :                       if (width <= 0)
    3983           0 :                         width = 1;
    3984           0 :                       tty_fprintf (fp, _("trust: %s"), otrust);
    3985           0 :                       tty_fprintf (fp, "%*s", width, "");
    3986             :                     }
    3987             : 
    3988           0 :                   tty_fprintf (fp, _("validity: %s"), trust);
    3989           0 :                   tty_fprintf (fp, "\n");
    3990             :                 }
    3991           0 :               if (node->pkt->pkttype == PKT_PUBLIC_KEY
    3992           0 :                   && (get_ownertrust (pk) & TRUST_FLAG_DISABLED))
    3993             :                 {
    3994           0 :                   tty_fprintf (fp, "*** ");
    3995           0 :                   tty_fprintf (fp, _("This key has been disabled"));
    3996           0 :                   tty_fprintf (fp, "\n");
    3997             :                 }
    3998             :             }
    3999             : 
    4000           0 :           if ((node->pkt->pkttype == PKT_PUBLIC_KEY
    4001           0 :                || node->pkt->pkttype == PKT_SECRET_KEY) && with_fpr)
    4002             :             {
    4003           0 :               print_fingerprint (fp, pk, 2);
    4004           0 :               tty_fprintf (fp, "\n");
    4005             :             }
    4006             :         }
    4007             :     }
    4008             : 
    4009           0 :   show_names (ctrl, fp,
    4010             :               keyblock, primary, only_marked ? NODFLG_MARK_A : 0, with_prefs);
    4011             : 
    4012           0 :   if (do_warn && !nowarn)
    4013           0 :     tty_fprintf (fp, _("Please note that the shown key validity"
    4014             :                        " is not necessarily correct\n"
    4015             :                        "unless you restart the program.\n"));
    4016             : 
    4017           0 :   xfree (serialno);
    4018             : }
    4019             : 
    4020             : 
    4021             : /* Display basic key information.  This function is suitable to show
    4022             :    information on the key without any dependencies on the trustdb or
    4023             :    any other internal GnuPG stuff.  KEYBLOCK may either be a public or
    4024             :    a secret key.  This function may be called with KEYBLOCK containing
    4025             :    secret keys and thus the printing of "pub" vs. "sec" does only
    4026             :    depend on the packet type and not by checking with gpg-agent.  */
    4027             : void
    4028           0 : show_basic_key_info (KBNODE keyblock)
    4029             : {
    4030             :   KBNODE node;
    4031             :   int i;
    4032             :   char pkstrbuf[PUBKEY_STRING_SIZE];
    4033             : 
    4034             :   /* The primary key */
    4035           0 :   for (node = keyblock; node; node = node->next)
    4036             :     {
    4037           0 :       if (node->pkt->pkttype == PKT_PUBLIC_KEY
    4038           0 :           || node->pkt->pkttype == PKT_SECRET_KEY)
    4039             :         {
    4040           0 :           PKT_public_key *pk = node->pkt->pkt.public_key;
    4041             : 
    4042             :           /* Note, we use the same format string as in other show
    4043             :              functions to make the translation job easier. */
    4044           0 :           tty_printf ("%s  %s/%s  ",
    4045           0 :                       node->pkt->pkttype == PKT_PUBLIC_KEY ? "pub" :
    4046           0 :                       node->pkt->pkttype == PKT_PUBLIC_SUBKEY ? "sub" :
    4047           0 :                       node->pkt->pkttype == PKT_SECRET_KEY ? "sec" :"ssb",
    4048             :                       pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
    4049             :                       keystr_from_pk (pk));
    4050           0 :           tty_printf (_("created: %s"), datestr_from_pk (pk));
    4051           0 :           tty_printf ("  ");
    4052           0 :           tty_printf (_("expires: %s"), expirestr_from_pk (pk));
    4053           0 :           tty_printf ("\n");
    4054           0 :           print_fingerprint (NULL, pk, 3);
    4055           0 :           tty_printf ("\n");
    4056             :         }
    4057             :     }
    4058             : 
    4059             :   /* The user IDs. */
    4060           0 :   for (i = 0, node = keyblock; node; node = node->next)
    4061             :     {
    4062           0 :       if (node->pkt->pkttype == PKT_USER_ID)
    4063             :         {
    4064           0 :           PKT_user_id *uid = node->pkt->pkt.user_id;
    4065           0 :           ++i;
    4066             : 
    4067           0 :           tty_printf ("     ");
    4068           0 :           if (uid->is_revoked)
    4069           0 :             tty_printf ("[%s] ", _("revoked"));
    4070           0 :           else if (uid->is_expired)
    4071           0 :             tty_printf ("[%s] ", _("expired"));
    4072           0 :           tty_print_utf8_string (uid->name, uid->len);
    4073           0 :           tty_printf ("\n");
    4074             :         }
    4075             :     }
    4076           0 : }
    4077             : 
    4078             : 
    4079             : static void
    4080           0 : show_key_and_fingerprint (kbnode_t keyblock, int with_subkeys)
    4081             : {
    4082             :   kbnode_t node;
    4083           0 :   PKT_public_key *pk = NULL;
    4084             :   char pkstrbuf[PUBKEY_STRING_SIZE];
    4085             : 
    4086           0 :   for (node = keyblock; node; node = node->next)
    4087             :     {
    4088           0 :       if (node->pkt->pkttype == PKT_PUBLIC_KEY)
    4089             :         {
    4090           0 :           pk = node->pkt->pkt.public_key;
    4091           0 :           tty_printf ("pub   %s/%s %s ",
    4092             :                       pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
    4093             :                       keystr_from_pk(pk),
    4094             :                       datestr_from_pk (pk));
    4095             :         }
    4096           0 :       else if (node->pkt->pkttype == PKT_USER_ID)
    4097             :         {
    4098           0 :           PKT_user_id *uid = node->pkt->pkt.user_id;
    4099           0 :           tty_print_utf8_string (uid->name, uid->len);
    4100           0 :           break;
    4101             :         }
    4102             :     }
    4103           0 :   tty_printf ("\n");
    4104           0 :   if (pk)
    4105           0 :     print_fingerprint (NULL, pk, 2);
    4106           0 :   if (with_subkeys)
    4107             :     {
    4108           0 :       for (node = keyblock; node; node = node->next)
    4109             :         {
    4110           0 :           if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
    4111             :             {
    4112           0 :               pk = node->pkt->pkt.public_key;
    4113           0 :               tty_printf ("sub   %s/%s %s [%s]\n",
    4114             :                           pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
    4115             :                           keystr_from_pk(pk),
    4116             :                           datestr_from_pk (pk),
    4117             :                           usagestr_from_pk (pk, 0));
    4118             : 
    4119           0 :               print_fingerprint (NULL, pk, 4);
    4120             :             }
    4121             :         }
    4122             :     }
    4123           0 : }
    4124             : 
    4125             : 
    4126             : /* Show a listing of the primary and its subkeys along with their
    4127             :    keygrips.  */
    4128             : static void
    4129           0 : show_key_and_grip (kbnode_t keyblock)
    4130             : {
    4131             :   kbnode_t node;
    4132           0 :   PKT_public_key *pk = NULL;
    4133             :   char pkstrbuf[PUBKEY_STRING_SIZE];
    4134             :   char *hexgrip;
    4135             : 
    4136           0 :   for (node = keyblock; node; node = node->next)
    4137             :     {
    4138           0 :       if (node->pkt->pkttype == PKT_PUBLIC_KEY
    4139           0 :           || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
    4140             :         {
    4141           0 :           pk = node->pkt->pkt.public_key;
    4142           0 :           tty_printf ("%s   %s/%s %s [%s]\n",
    4143           0 :                       node->pkt->pkttype == PKT_PUBLIC_KEY? "pub":"sub",
    4144             :                       pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
    4145             :                       keystr_from_pk(pk),
    4146             :                       datestr_from_pk (pk),
    4147             :                       usagestr_from_pk (pk, 0));
    4148             : 
    4149           0 :           if (!hexkeygrip_from_pk (pk, &hexgrip))
    4150             :             {
    4151           0 :               tty_printf ("      Keygrip: %s\n", hexgrip);
    4152           0 :               xfree (hexgrip);
    4153             :             }
    4154             :         }
    4155             :     }
    4156           0 : }
    4157             : 
    4158             : 
    4159             : /* Show a warning if no uids on the key have the primary uid flag
    4160             :    set. */
    4161             : static void
    4162           0 : no_primary_warning (KBNODE keyblock)
    4163             : {
    4164             :   KBNODE node;
    4165           0 :   int have_primary = 0, uid_count = 0;
    4166             : 
    4167             :   /* TODO: if we ever start behaving differently with a primary or
    4168             :      non-primary attribute ID, we will need to check for attributes
    4169             :      here as well. */
    4170             : 
    4171           0 :   for (node = keyblock; node; node = node->next)
    4172             :     {
    4173           0 :       if (node->pkt->pkttype == PKT_USER_ID
    4174           0 :           && node->pkt->pkt.user_id->attrib_data == NULL)
    4175             :         {
    4176           0 :           uid_count++;
    4177             : 
    4178           0 :           if (node->pkt->pkt.user_id->is_primary == 2)
    4179             :             {
    4180           0 :               have_primary = 1;
    4181           0 :               break;
    4182             :             }
    4183             :         }
    4184             :     }
    4185             : 
    4186           0 :   if (uid_count > 1 && !have_primary)
    4187           0 :     log_info (_
    4188             :               ("WARNING: no user ID has been marked as primary.  This command"
    4189             :                " may\n              cause a different user ID to become"
    4190             :                " the assumed primary.\n"));
    4191           0 : }
    4192             : 
    4193             : 
    4194             : /* Print a warning if the latest encryption subkey expires soon.  This
    4195             :    function is called after the expire data of the primary key has
    4196             :    been changed.  */
    4197             : static void
    4198           0 : subkey_expire_warning (kbnode_t keyblock)
    4199             : {
    4200           0 :   u32 curtime = make_timestamp ();
    4201             :   kbnode_t node;
    4202             :   PKT_public_key *pk;
    4203             :   /* u32 mainexpire = 0; */
    4204           0 :   u32 subexpire = 0;
    4205           0 :   u32 latest_date = 0;
    4206             : 
    4207           0 :   for (node = keyblock; node; node = node->next)
    4208             :     {
    4209             :       /* if (node->pkt->pkttype == PKT_PUBLIC_KEY) */
    4210             :       /*   { */
    4211             :       /*     pk = node->pkt->pkt.public_key; */
    4212             :       /*     mainexpire = pk->expiredate; */
    4213             :       /*   } */
    4214             : 
    4215           0 :       if (node->pkt->pkttype != PKT_PUBLIC_SUBKEY)
    4216           0 :         continue;
    4217           0 :       pk = node->pkt->pkt.public_key;
    4218             : 
    4219           0 :       if (!pk->flags.valid)
    4220           0 :         continue;
    4221           0 :       if (pk->flags.revoked)
    4222           0 :         continue;
    4223           0 :       if (pk->timestamp > curtime)
    4224           0 :         continue; /* Ignore future keys.  */
    4225           0 :       if (!(pk->pubkey_usage & PUBKEY_USAGE_ENC))
    4226           0 :         continue; /* Not an encryption key.  */
    4227             : 
    4228           0 :       if (pk->timestamp > latest_date || (!pk->timestamp && !latest_date))
    4229             :         {
    4230           0 :           latest_date = pk->timestamp;
    4231           0 :           subexpire = pk->expiredate;
    4232             :         }
    4233             :     }
    4234             : 
    4235           0 :   if (!subexpire)
    4236           0 :     return;  /* No valid subkey with an expiration time.  */
    4237             : 
    4238           0 :   if (curtime + (10*86400) > subexpire)
    4239             :     {
    4240           0 :       log_info (_("WARNING: Your encryption subkey expires soon.\n"));
    4241           0 :       log_info (_("You may want to change its expiration date too.\n"));
    4242             :     }
    4243             : }
    4244             : 
    4245             : 
    4246             : /*
    4247             :  * Ask for a new user id, add the self-signature, and update the
    4248             :  * keyblock.  If UIDSTRING is not NULL the user ID is generated
    4249             :  * unattended using that string.  UIDSTRING is expected to be utf-8
    4250             :  * encoded and white space trimmed.  Returns true if there is a new
    4251             :  * user id.
    4252             :  */
    4253             : static int
    4254           1 : menu_adduid (ctrl_t ctrl, kbnode_t pub_keyblock,
    4255             :              int photo, const char *photo_name, const char *uidstring)
    4256             : {
    4257             :   PKT_user_id *uid;
    4258           1 :   PKT_public_key *pk = NULL;
    4259           1 :   PKT_signature *sig = NULL;
    4260             :   PACKET *pkt;
    4261             :   KBNODE node;
    4262           1 :   KBNODE pub_where = NULL;
    4263             :   gpg_error_t err;
    4264             : 
    4265           1 :   if (photo && uidstring)
    4266           0 :     return 0;  /* Not allowed.  */
    4267             : 
    4268           4 :   for (node = pub_keyblock; node; pub_where = node, node = node->next)
    4269             :     {
    4270           4 :       if (node->pkt->pkttype == PKT_PUBLIC_KEY)
    4271           1 :         pk = node->pkt->pkt.public_key;
    4272           3 :       else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
    4273           1 :         break;
    4274             :     }
    4275           1 :   if (!node) /* No subkey.  */
    4276           0 :     pub_where = NULL;
    4277           1 :   log_assert (pk);
    4278             : 
    4279           1 :   if (photo)
    4280             :     {
    4281           0 :       int hasattrib = 0;
    4282             : 
    4283           0 :       for (node = pub_keyblock; node; node = node->next)
    4284           0 :         if (node->pkt->pkttype == PKT_USER_ID &&
    4285           0 :             node->pkt->pkt.user_id->attrib_data != NULL)
    4286             :           {
    4287           0 :             hasattrib = 1;
    4288           0 :             break;
    4289             :           }
    4290             : 
    4291             :       /* It is legal but bad for compatibility to add a photo ID to a
    4292             :          v3 key as it means that PGP2 will not be able to use that key
    4293             :          anymore.  Also, PGP may not expect a photo on a v3 key.
    4294             :          Don't bother to ask this if the key already has a photo - any
    4295             :          damage has already been done at that point. -dms */
    4296           0 :       if (pk->version == 3 && !hasattrib)
    4297             :         {
    4298           0 :           if (opt.expert)
    4299             :             {
    4300           0 :               tty_printf (_("WARNING: This is a PGP2-style key.  "
    4301             :                             "Adding a photo ID may cause some versions\n"
    4302             :                             "         of PGP to reject this key.\n"));
    4303             : 
    4304           0 :               if (!cpr_get_answer_is_yes ("keyedit.v3_photo.okay",
    4305           0 :                                           _("Are you sure you still want "
    4306             :                                             "to add it? (y/N) ")))
    4307           0 :                 return 0;
    4308             :             }
    4309             :           else
    4310             :             {
    4311           0 :               tty_printf (_("You may not add a photo ID to "
    4312             :                             "a PGP2-style key.\n"));
    4313           0 :               return 0;
    4314             :             }
    4315             :         }
    4316             : 
    4317           0 :       uid = generate_photo_id (ctrl, pk, photo_name);
    4318             :     }
    4319             :   else
    4320           1 :     uid = generate_user_id (pub_keyblock, uidstring);
    4321           1 :   if (!uid)
    4322             :     {
    4323           0 :       if (uidstring)
    4324             :         {
    4325           0 :           write_status_error ("adduid", gpg_error (304));
    4326           0 :           log_error ("%s", _("Such a user ID already exists on this key!\n"));
    4327             :         }
    4328           0 :       return 0;
    4329             :     }
    4330             : 
    4331           1 :   err = make_keysig_packet (&sig, pk, uid, NULL, pk, 0x13, 0, 0, 0,
    4332             :                             keygen_add_std_prefs, pk, NULL);
    4333           1 :   if (err)
    4334             :     {
    4335           0 :       write_status_error ("keysig", err);
    4336           0 :       log_error ("signing failed: %s\n", gpg_strerror (err));
    4337           0 :       free_user_id (uid);
    4338           0 :       return 0;
    4339             :     }
    4340             : 
    4341             :   /* Insert/append to public keyblock */
    4342           1 :   pkt = xmalloc_clear (sizeof *pkt);
    4343           1 :   pkt->pkttype = PKT_USER_ID;
    4344           1 :   pkt->pkt.user_id = uid;
    4345           1 :   node = new_kbnode (pkt);
    4346           1 :   if (pub_where)
    4347           1 :     insert_kbnode (pub_where, node, 0);
    4348             :   else
    4349           0 :     add_kbnode (pub_keyblock, node);
    4350           1 :   pkt = xmalloc_clear (sizeof *pkt);
    4351           1 :   pkt->pkttype = PKT_SIGNATURE;
    4352           1 :   pkt->pkt.signature = sig;
    4353           1 :   if (pub_where)
    4354           1 :     insert_kbnode (node, new_kbnode (pkt), 0);
    4355             :   else
    4356           0 :     add_kbnode (pub_keyblock, new_kbnode (pkt));
    4357           1 :   return 1;
    4358             : }
    4359             : 
    4360             : 
    4361             : /*
    4362             :  * Remove all selected userids from the keyring
    4363             :  */
    4364             : static void
    4365           0 : menu_deluid (KBNODE pub_keyblock)
    4366             : {
    4367             :   KBNODE node;
    4368           0 :   int selected = 0;
    4369             : 
    4370           0 :   for (node = pub_keyblock; node; node = node->next)
    4371             :     {
    4372           0 :       if (node->pkt->pkttype == PKT_USER_ID)
    4373             :         {
    4374           0 :           selected = node->flag & NODFLG_SELUID;
    4375           0 :           if (selected)
    4376             :             {
    4377             :               /* Only cause a trust update if we delete a
    4378             :                  non-revoked user id */
    4379           0 :               if (!node->pkt->pkt.user_id->is_revoked)
    4380           0 :                 update_trust = 1;
    4381           0 :               delete_kbnode (node);
    4382             :             }
    4383             :         }
    4384           0 :       else if (selected && node->pkt->pkttype == PKT_SIGNATURE)
    4385           0 :         delete_kbnode (node);
    4386           0 :       else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
    4387           0 :         selected = 0;
    4388             :     }
    4389           0 :   commit_kbnode (&pub_keyblock);
    4390           0 : }
    4391             : 
    4392             : 
    4393             : static int
    4394           0 : menu_delsig (KBNODE pub_keyblock)
    4395             : {
    4396             :   KBNODE node;
    4397           0 :   PKT_user_id *uid = NULL;
    4398           0 :   int changed = 0;
    4399             : 
    4400           0 :   for (node = pub_keyblock; node; node = node->next)
    4401             :     {
    4402           0 :       if (node->pkt->pkttype == PKT_USER_ID)
    4403             :         {
    4404           0 :           uid = (node->flag & NODFLG_SELUID) ? node->pkt->pkt.user_id : NULL;
    4405             :         }
    4406           0 :       else if (uid && node->pkt->pkttype == PKT_SIGNATURE)
    4407           0 :         {
    4408             :           int okay, valid, selfsig, inv_sig, no_key, other_err;
    4409             : 
    4410           0 :           tty_printf ("uid  ");
    4411           0 :           tty_print_utf8_string (uid->name, uid->len);
    4412           0 :           tty_printf ("\n");
    4413             : 
    4414           0 :           okay = inv_sig = no_key = other_err = 0;
    4415           0 :           if (opt.with_colons)
    4416           0 :             valid = print_and_check_one_sig_colon (pub_keyblock, node,
    4417             :                                                    &inv_sig, &no_key,
    4418             :                                                    &other_err, &selfsig, 1);
    4419             :           else
    4420           0 :             valid = print_and_check_one_sig (pub_keyblock, node,
    4421             :                                              &inv_sig, &no_key, &other_err,
    4422             :                                              &selfsig, 1, 0);
    4423             : 
    4424           0 :           if (valid)
    4425             :             {
    4426           0 :               okay = cpr_get_answer_yes_no_quit
    4427             :                 ("keyedit.delsig.valid",
    4428           0 :                  _("Delete this good signature? (y/N/q)"));
    4429             : 
    4430             :               /* Only update trust if we delete a good signature.
    4431             :                  The other two cases do not affect trust. */
    4432           0 :               if (okay)
    4433           0 :                 update_trust = 1;
    4434             :             }
    4435           0 :           else if (inv_sig || other_err)
    4436           0 :             okay = cpr_get_answer_yes_no_quit
    4437             :               ("keyedit.delsig.invalid",
    4438           0 :                _("Delete this invalid signature? (y/N/q)"));
    4439           0 :           else if (no_key)
    4440           0 :             okay = cpr_get_answer_yes_no_quit
    4441             :               ("keyedit.delsig.unknown",
    4442           0 :                _("Delete this unknown signature? (y/N/q)"));
    4443             : 
    4444           0 :           if (okay == -1)
    4445           0 :             break;
    4446           0 :           if (okay && selfsig
    4447           0 :               && !cpr_get_answer_is_yes
    4448             :               ("keyedit.delsig.selfsig",
    4449           0 :                _("Really delete this self-signature? (y/N)")))
    4450           0 :             okay = 0;
    4451           0 :           if (okay)
    4452             :             {
    4453           0 :               delete_kbnode (node);
    4454           0 :               changed++;
    4455             :             }
    4456             : 
    4457             :         }
    4458           0 :       else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
    4459           0 :         uid = NULL;
    4460             :     }
    4461             : 
    4462           0 :   if (changed)
    4463             :     {
    4464           0 :       commit_kbnode (&pub_keyblock);
    4465           0 :       tty_printf (ngettext("Deleted %d signature.\n",
    4466             :                            "Deleted %d signatures.\n", changed), changed);
    4467             :     }
    4468             :   else
    4469           0 :     tty_printf (_("Nothing deleted.\n"));
    4470             : 
    4471           0 :   return changed;
    4472             : }
    4473             : 
    4474             : 
    4475             : static int
    4476           0 : menu_clean (KBNODE keyblock, int self_only)
    4477             : {
    4478             :   KBNODE uidnode;
    4479           0 :   int modified = 0, select_all = !count_selected_uids (keyblock);
    4480             : 
    4481           0 :   for (uidnode = keyblock->next;
    4482           0 :        uidnode && uidnode->pkt->pkttype != PKT_PUBLIC_SUBKEY;
    4483           0 :        uidnode = uidnode->next)
    4484             :     {
    4485           0 :       if (uidnode->pkt->pkttype == PKT_USER_ID
    4486           0 :           && (uidnode->flag & NODFLG_SELUID || select_all))
    4487             :         {
    4488           0 :           int uids = 0, sigs = 0;
    4489           0 :           char *user = utf8_to_native (uidnode->pkt->pkt.user_id->name,
    4490           0 :                                        uidnode->pkt->pkt.user_id->len,
    4491             :                                        0);
    4492             : 
    4493           0 :           clean_one_uid (keyblock, uidnode, opt.verbose, self_only, &uids,
    4494             :                          &sigs);
    4495           0 :           if (uids)
    4496             :             {
    4497             :               const char *reason;
    4498             : 
    4499           0 :               if (uidnode->pkt->pkt.user_id->is_revoked)
    4500           0 :                 reason = _("revoked");
    4501           0 :               else if (uidnode->pkt->pkt.user_id->is_expired)
    4502           0 :                 reason = _("expired");
    4503             :               else
    4504           0 :                 reason = _("invalid");
    4505             : 
    4506           0 :               tty_printf (_("User ID \"%s\" compacted: %s\n"), user, reason);
    4507             : 
    4508           0 :               modified = 1;
    4509             :             }
    4510           0 :           else if (sigs)
    4511             :             {
    4512           0 :               tty_printf (ngettext("User ID \"%s\": %d signature removed\n",
    4513             :                                    "User ID \"%s\": %d signatures removed\n",
    4514             :                                    sigs), user, sigs);
    4515           0 :               modified = 1;
    4516             :             }
    4517             :           else
    4518             :             {
    4519           0 :               tty_printf (self_only == 1 ?
    4520             :                           _("User ID \"%s\": already minimized\n") :
    4521             :                           _("User ID \"%s\": already clean\n"), user);
    4522             :             }
    4523             : 
    4524           0 :           xfree (user);
    4525             :         }
    4526             :     }
    4527             : 
    4528           0 :   return modified;
    4529             : }
    4530             : 
    4531             : 
    4532             : /*
    4533             :  * Remove some of the secondary keys
    4534             :  */
    4535             : static void
    4536           0 : menu_delkey (KBNODE pub_keyblock)
    4537             : {
    4538             :   KBNODE node;
    4539           0 :   int selected = 0;
    4540             : 
    4541           0 :   for (node = pub_keyblock; node; node = node->next)
    4542             :     {
    4543           0 :       if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
    4544             :         {
    4545           0 :           selected = node->flag & NODFLG_SELKEY;
    4546           0 :           if (selected)
    4547           0 :             delete_kbnode (node);
    4548             :         }
    4549           0 :       else if (selected && node->pkt->pkttype == PKT_SIGNATURE)
    4550           0 :         delete_kbnode (node);
    4551             :       else
    4552           0 :         selected = 0;
    4553             :     }
    4554           0 :   commit_kbnode (&pub_keyblock);
    4555             : 
    4556             :   /* No need to set update_trust here since signing keys are no
    4557             :      longer used to certify other keys, so there is no change in
    4558             :      trust when revoking/removing them.   */
    4559           0 : }
    4560             : 
    4561             : 
    4562             : /*
    4563             :  * Ask for a new revoker, create the self-signature and put it into
    4564             :  * the keyblock.  Returns true if there is a new revoker.
    4565             :  */
    4566             : static int
    4567           0 : menu_addrevoker (ctrl_t ctrl, kbnode_t pub_keyblock, int sensitive)
    4568             : {
    4569           0 :   PKT_public_key *pk = NULL;
    4570           0 :   PKT_public_key *revoker_pk = NULL;
    4571           0 :   PKT_signature *sig = NULL;
    4572             :   PACKET *pkt;
    4573             :   struct revocation_key revkey;
    4574             :   size_t fprlen;
    4575             :   int rc;
    4576             : 
    4577           0 :   log_assert (pub_keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
    4578             : 
    4579           0 :   pk = pub_keyblock->pkt->pkt.public_key;
    4580             : 
    4581           0 :   if (pk->numrevkeys == 0 && pk->version == 3)
    4582             :     {
    4583             :       /* It is legal but bad for compatibility to add a revoker to a
    4584             :          v3 key as it means that PGP2 will not be able to use that key
    4585             :          anymore.  Also, PGP may not expect a revoker on a v3 key.
    4586             :          Don't bother to ask this if the key already has a revoker -
    4587             :          any damage has already been done at that point. -dms */
    4588           0 :       if (opt.expert)
    4589             :         {
    4590           0 :           tty_printf (_("WARNING: This is a PGP 2.x-style key.  "
    4591             :                         "Adding a designated revoker may cause\n"
    4592             :                         "         some versions of PGP to reject this key.\n"));
    4593             : 
    4594           0 :           if (!cpr_get_answer_is_yes ("keyedit.v3_revoker.okay",
    4595           0 :                                       _("Are you sure you still want "
    4596             :                                         "to add it? (y/N) ")))
    4597           0 :             return 0;
    4598             :         }
    4599             :       else
    4600             :         {
    4601           0 :           tty_printf (_("You may not add a designated revoker to "
    4602             :                         "a PGP 2.x-style key.\n"));
    4603           0 :           return 0;
    4604             :         }
    4605             :     }
    4606             : 
    4607             :   for (;;)
    4608             :     {
    4609             :       char *answer;
    4610             : 
    4611           0 :       free_public_key (revoker_pk);
    4612           0 :       revoker_pk = xmalloc_clear (sizeof (*revoker_pk));
    4613             : 
    4614           0 :       tty_printf ("\n");
    4615             : 
    4616           0 :       answer = cpr_get_utf8
    4617             :         ("keyedit.add_revoker",
    4618           0 :          _("Enter the user ID of the designated revoker: "));
    4619           0 :       if (answer[0] == '\0' || answer[0] == CONTROL_D)
    4620             :         {
    4621           0 :           xfree (answer);
    4622           0 :           goto fail;
    4623             :         }
    4624             : 
    4625             :       /* Note that I'm requesting CERT here, which usually implies
    4626             :          primary keys only, but some casual testing shows that PGP and
    4627             :          GnuPG both can handle a designated revocation from a subkey. */
    4628           0 :       revoker_pk->req_usage = PUBKEY_USAGE_CERT;
    4629           0 :       rc = get_pubkey_byname (ctrl, NULL, revoker_pk, answer, NULL, NULL, 1, 1);
    4630           0 :       if (rc)
    4631             :         {
    4632           0 :           log_error (_("key \"%s\" not found: %s\n"), answer,
    4633             :                      gpg_strerror (rc));
    4634           0 :           xfree (answer);
    4635           0 :           continue;
    4636             :         }
    4637             : 
    4638           0 :       xfree (answer);
    4639             : 
    4640           0 :       fingerprint_from_pk (revoker_pk, revkey.fpr, &fprlen);
    4641           0 :       if (fprlen != 20)
    4642             :         {
    4643           0 :           log_error (_("cannot appoint a PGP 2.x style key as a "
    4644             :                        "designated revoker\n"));
    4645           0 :           continue;
    4646             :         }
    4647             : 
    4648           0 :       revkey.class = 0x80;
    4649           0 :       if (sensitive)
    4650           0 :         revkey.class |= 0x40;
    4651           0 :       revkey.algid = revoker_pk->pubkey_algo;
    4652             : 
    4653           0 :       if (cmp_public_keys (revoker_pk, pk) == 0)
    4654             :         {
    4655             :           /* This actually causes no harm (after all, a key that
    4656             :              designates itself as a revoker is the same as a
    4657             :              regular key), but it's easy enough to check. */
    4658           0 :           log_error (_("you cannot appoint a key as its own "
    4659             :                        "designated revoker\n"));
    4660             : 
    4661           0 :           continue;
    4662             :         }
    4663             : 
    4664           0 :       keyid_from_pk (pk, NULL);
    4665             : 
    4666             :       /* Does this revkey already exist? */
    4667           0 :       if (!pk->revkey && pk->numrevkeys)
    4668           0 :         BUG ();
    4669             :       else
    4670             :         {
    4671             :           int i;
    4672             : 
    4673           0 :           for (i = 0; i < pk->numrevkeys; i++)
    4674             :             {
    4675           0 :               if (memcmp (&pk->revkey[i], &revkey,
    4676             :                           sizeof (struct revocation_key)) == 0)
    4677             :                 {
    4678             :                   char buf[50];
    4679             : 
    4680           0 :                   log_error (_("this key has already been designated "
    4681             :                                "as a revoker\n"));
    4682             : 
    4683           0 :                   format_keyid (pk_keyid (pk), KF_LONG, buf, sizeof (buf));
    4684           0 :                   write_status_text (STATUS_ALREADY_SIGNED, buf);
    4685             : 
    4686           0 :                   break;
    4687             :                 }
    4688             :             }
    4689             : 
    4690           0 :           if (i < pk->numrevkeys)
    4691           0 :             continue;
    4692             :         }
    4693             : 
    4694           0 :       print_pubkey_info (NULL, revoker_pk);
    4695           0 :       print_fingerprint (NULL, revoker_pk, 2);
    4696           0 :       tty_printf ("\n");
    4697             : 
    4698           0 :       tty_printf (_("WARNING: appointing a key as a designated revoker "
    4699             :                     "cannot be undone!\n"));
    4700             : 
    4701           0 :       tty_printf ("\n");
    4702             : 
    4703           0 :       if (!cpr_get_answer_is_yes ("keyedit.add_revoker.okay",
    4704           0 :                                   _("Are you sure you want to appoint this "
    4705             :                                     "key as a designated revoker? (y/N) ")))
    4706           0 :         continue;
    4707             : 
    4708           0 :       free_public_key (revoker_pk);
    4709           0 :       revoker_pk = NULL;
    4710           0 :       break;
    4711           0 :     }
    4712             : 
    4713           0 :   rc = make_keysig_packet (&sig, pk, NULL, NULL, pk, 0x1F, 0, 0, 0,
    4714             :                            keygen_add_revkey, &revkey, NULL);
    4715           0 :   if (rc)
    4716             :     {
    4717           0 :       write_status_error ("keysig", rc);
    4718           0 :       log_error ("signing failed: %s\n", gpg_strerror (rc));
    4719           0 :       goto fail;
    4720             :     }
    4721             : 
    4722             :   /* Insert into public keyblock.  */
    4723           0 :   pkt = xmalloc_clear (sizeof *pkt);
    4724           0 :   pkt->pkttype = PKT_SIGNATURE;
    4725           0 :   pkt->pkt.signature = sig;
    4726           0 :   insert_kbnode (pub_keyblock, new_kbnode (pkt), PKT_SIGNATURE);
    4727             : 
    4728           0 :   return 1;
    4729             : 
    4730             : fail:
    4731           0 :   if (sig)
    4732           0 :     free_seckey_enc (sig);
    4733           0 :   free_public_key (revoker_pk);
    4734             : 
    4735           0 :   return 0;
    4736             : }
    4737             : 
    4738             : 
    4739             : static int
    4740           0 : menu_expire (KBNODE pub_keyblock)
    4741             : {
    4742             :   int n1, signumber, rc;
    4743             :   u32 expiredate;
    4744           0 :   int mainkey = 0;
    4745             :   PKT_public_key *main_pk, *sub_pk;
    4746             :   PKT_user_id *uid;
    4747             :   KBNODE node;
    4748             :   u32 keyid[2];
    4749             : 
    4750           0 :   n1 = count_selected_keys (pub_keyblock);
    4751           0 :   if (n1 > 1)
    4752             :     {
    4753           0 :       if (!cpr_get_answer_is_yes
    4754             :           ("keyedit.expire_multiple_subkeys.okay",
    4755           0 :            _("Are you sure you want to change the"
    4756             :              " expiration time for multiple subkeys? (y/N) ")))
    4757           0 :         return 0;
    4758             :     }
    4759           0 :   else if (n1)
    4760           0 :     tty_printf (_("Changing expiration time for a subkey.\n"));
    4761             :   else
    4762             :     {
    4763           0 :       tty_printf (_("Changing expiration time for the primary key.\n"));
    4764           0 :       mainkey = 1;
    4765           0 :       no_primary_warning (pub_keyblock);
    4766             :     }
    4767             : 
    4768           0 :   expiredate = ask_expiredate ();
    4769             : 
    4770             :   /* Now we can actually change the self-signature(s) */
    4771           0 :   main_pk = sub_pk = NULL;
    4772           0 :   uid = NULL;
    4773           0 :   signumber = 0;
    4774           0 :   for (node = pub_keyblock; node; node = node->next)
    4775             :     {
    4776           0 :       if (node->pkt->pkttype == PKT_PUBLIC_KEY)
    4777             :         {
    4778           0 :           main_pk = node->pkt->pkt.public_key;
    4779           0 :           keyid_from_pk (main_pk, keyid);
    4780           0 :           main_pk->expiredate = expiredate;
    4781             :         }
    4782           0 :       else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
    4783             :         {
    4784           0 :           if (node->flag & NODFLG_SELKEY)
    4785             :             {
    4786           0 :               sub_pk = node->pkt->pkt.public_key;
    4787           0 :               sub_pk->expiredate = expiredate;
    4788             :             }
    4789             :           else
    4790           0 :             sub_pk = NULL;
    4791             :         }
    4792           0 :       else if (node->pkt->pkttype == PKT_USER_ID)
    4793           0 :         uid = node->pkt->pkt.user_id;
    4794           0 :       else if (main_pk && node->pkt->pkttype == PKT_SIGNATURE
    4795           0 :                && (mainkey || sub_pk))
    4796             :         {
    4797           0 :           PKT_signature *sig = node->pkt->pkt.signature;
    4798           0 :           if (keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
    4799           0 :               && ((mainkey && uid
    4800           0 :                    && uid->created && (sig->sig_class & ~3) == 0x10)
    4801           0 :                   || (!mainkey && sig->sig_class == 0x18))
    4802           0 :               && sig->flags.chosen_selfsig)
    4803             :             {
    4804             :               /* This is a self-signature which is to be replaced.  */
    4805             :               PKT_signature *newsig;
    4806             :               PACKET *newpkt;
    4807             : 
    4808           0 :               signumber++;
    4809             : 
    4810           0 :               if ((mainkey && main_pk->version < 4)
    4811           0 :                   || (!mainkey && sub_pk->version < 4))
    4812             :                 {
    4813           0 :                   log_info
    4814           0 :                     (_("You can't change the expiration date of a v3 key\n"));
    4815           0 :                   return 0;
    4816             :                 }
    4817             : 
    4818           0 :               if (mainkey)
    4819           0 :                 rc = update_keysig_packet (&newsig, sig, main_pk, uid, NULL,
    4820             :                                            main_pk, keygen_add_key_expire,
    4821             :                                            main_pk);
    4822             :               else
    4823           0 :                 rc =
    4824           0 :                   update_keysig_packet (&newsig, sig, main_pk, NULL, sub_pk,
    4825             :                                         main_pk, keygen_add_key_expire, sub_pk);
    4826           0 :               if (rc)
    4827             :                 {
    4828           0 :                   log_error ("make_keysig_packet failed: %s\n",
    4829             :                              gpg_strerror (rc));
    4830           0 :                   return 0;
    4831             :                 }
    4832             : 
    4833             :               /* Replace the packet.  */
    4834           0 :               newpkt = xmalloc_clear (sizeof *newpkt);
    4835           0 :               newpkt->pkttype = PKT_SIGNATURE;
    4836           0 :               newpkt->pkt.signature = newsig;
    4837           0 :               free_packet (node->pkt);
    4838           0 :               xfree (node->pkt);
    4839           0 :               node->pkt = newpkt;
    4840           0 :               sub_pk = NULL;
    4841             :             }
    4842             :         }
    4843             :     }
    4844             : 
    4845           0 :   update_trust = 1;
    4846           0 :   return 1;
    4847             : }
    4848             : 
    4849             : 
    4850             : /* Change the capability of a selected key.  This command should only
    4851             :  * be used to rectify badly created keys and as such is not suggested
    4852             :  * for general use.  */
    4853             : static int
    4854           0 : menu_changeusage (kbnode_t keyblock)
    4855             : {
    4856             :   int n1, rc;
    4857           0 :   int mainkey = 0;
    4858             :   PKT_public_key *main_pk, *sub_pk;
    4859             :   PKT_user_id *uid;
    4860             :   kbnode_t node;
    4861             :   u32 keyid[2];
    4862             : 
    4863           0 :   n1 = count_selected_keys (keyblock);
    4864           0 :   if (n1 > 1)
    4865             :     {
    4866           0 :       tty_printf (_("You must select exactly one key.\n"));
    4867           0 :       return 0;
    4868             :     }
    4869           0 :   else if (n1)
    4870           0 :     tty_printf ("Changing usage of a subkey.\n");
    4871             :   else
    4872             :     {
    4873           0 :       tty_printf ("Changing usage of the primary key.\n");
    4874           0 :       mainkey = 1;
    4875             :     }
    4876             : 
    4877             :   /* Now we can actually change the self-signature(s) */
    4878           0 :   main_pk = sub_pk = NULL;
    4879           0 :   uid = NULL;
    4880           0 :   for (node = keyblock; node; node = node->next)
    4881             :     {
    4882           0 :       if (node->pkt->pkttype == PKT_PUBLIC_KEY)
    4883             :         {
    4884           0 :           main_pk = node->pkt->pkt.public_key;
    4885           0 :           keyid_from_pk (main_pk, keyid);
    4886             :         }
    4887           0 :       else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
    4888             :         {
    4889           0 :           if (node->flag & NODFLG_SELKEY)
    4890           0 :             sub_pk = node->pkt->pkt.public_key;
    4891             :           else
    4892           0 :             sub_pk = NULL;
    4893             :         }
    4894           0 :       else if (node->pkt->pkttype == PKT_USER_ID)
    4895           0 :         uid = node->pkt->pkt.user_id;
    4896           0 :       else if (main_pk && node->pkt->pkttype == PKT_SIGNATURE
    4897           0 :                && (mainkey || sub_pk))
    4898             :         {
    4899           0 :           PKT_signature *sig = node->pkt->pkt.signature;
    4900           0 :           if (keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
    4901           0 :               && ((mainkey && uid
    4902           0 :                    && uid->created && (sig->sig_class & ~3) == 0x10)
    4903           0 :                   || (!mainkey && sig->sig_class == 0x18))
    4904           0 :               && sig->flags.chosen_selfsig)
    4905             :             {
    4906             :               /* This is the self-signature which is to be replaced.  */
    4907             :               PKT_signature *newsig;
    4908             :               PACKET *newpkt;
    4909             : 
    4910           0 :               if ((mainkey && main_pk->version < 4)
    4911           0 :                   || (!mainkey && sub_pk->version < 4))
    4912             :                 {
    4913           0 :                   log_info ("You can't change the capabilities of a v3 key\n");
    4914           0 :                   return 0;
    4915             :                 }
    4916             : 
    4917           0 :               if (mainkey)
    4918           0 :                 main_pk->pubkey_usage = ask_key_flags (main_pk->pubkey_algo, 0,
    4919           0 :                                                        main_pk->pubkey_usage);
    4920             :               else
    4921           0 :                 sub_pk->pubkey_usage  = ask_key_flags (sub_pk->pubkey_algo, 1,
    4922           0 :                                                        sub_pk->pubkey_usage);
    4923             : 
    4924           0 :               if (mainkey)
    4925           0 :                 rc = update_keysig_packet (&newsig, sig, main_pk, uid, NULL,
    4926             :                                            main_pk, keygen_add_key_flags,
    4927             :                                            main_pk);
    4928             :               else
    4929           0 :                 rc =
    4930           0 :                   update_keysig_packet (&newsig, sig, main_pk, NULL, sub_pk,
    4931             :                                         main_pk, keygen_add_key_flags, sub_pk);
    4932           0 :               if (rc)
    4933             :                 {
    4934           0 :                   log_error ("make_keysig_packet failed: %s\n",
    4935             :                              gpg_strerror (rc));
    4936           0 :                   return 0;
    4937             :                 }
    4938             : 
    4939             :               /* Replace the packet.  */
    4940           0 :               newpkt = xmalloc_clear (sizeof *newpkt);
    4941           0 :               newpkt->pkttype = PKT_SIGNATURE;
    4942           0 :               newpkt->pkt.signature = newsig;
    4943           0 :               free_packet (node->pkt);
    4944           0 :               xfree (node->pkt);
    4945           0 :               node->pkt = newpkt;
    4946           0 :               sub_pk = NULL;
    4947           0 :               break;
    4948             :             }
    4949             :         }
    4950             :     }
    4951             : 
    4952           0 :   return 1;
    4953             : }
    4954             : 
    4955             : 
    4956             : static int
    4957           0 : menu_backsign (KBNODE pub_keyblock)
    4958             : {
    4959           0 :   int rc, modified = 0;
    4960             :   PKT_public_key *main_pk;
    4961             :   KBNODE node;
    4962             :   u32 timestamp;
    4963             : 
    4964           0 :   log_assert (pub_keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
    4965             : 
    4966           0 :   merge_keys_and_selfsig (pub_keyblock);
    4967           0 :   main_pk = pub_keyblock->pkt->pkt.public_key;
    4968           0 :   keyid_from_pk (main_pk, NULL);
    4969             : 
    4970             :   /* We use the same timestamp for all backsigs so that we don't
    4971             :      reveal information about the used machine.  */
    4972           0 :   timestamp = make_timestamp ();
    4973             : 
    4974           0 :   for (node = pub_keyblock; node; node = node->next)
    4975             :     {
    4976           0 :       PKT_public_key *sub_pk = NULL;
    4977           0 :       KBNODE node2, sig_pk = NULL /*,sig_sk = NULL*/;
    4978             :       /* char *passphrase; */
    4979             : 
    4980             :       /* Find a signing subkey with no backsig */
    4981           0 :       if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
    4982             :         {
    4983           0 :           if (node->pkt->pkt.public_key->pubkey_usage & PUBKEY_USAGE_SIG)
    4984             :             {
    4985           0 :               if (node->pkt->pkt.public_key->flags.backsig)
    4986           0 :                 tty_printf (_
    4987             :                             ("signing subkey %s is already cross-certified\n"),
    4988           0 :                             keystr_from_pk (node->pkt->pkt.public_key));
    4989             :               else
    4990           0 :                 sub_pk = node->pkt->pkt.public_key;
    4991             :             }
    4992             :           else
    4993           0 :             tty_printf (_("subkey %s does not sign and so does"
    4994             :                           " not need to be cross-certified\n"),
    4995           0 :                         keystr_from_pk (node->pkt->pkt.public_key));
    4996             :         }
    4997             : 
    4998           0 :       if (!sub_pk)
    4999           0 :         continue;
    5000             : 
    5001             :       /* Find the selected selfsig on this subkey */
    5002           0 :       for (node2 = node->next;
    5003           0 :            node2 && node2->pkt->pkttype == PKT_SIGNATURE; node2 = node2->next)
    5004           0 :         if (node2->pkt->pkt.signature->version >= 4
    5005           0 :             && node2->pkt->pkt.signature->flags.chosen_selfsig)
    5006             :           {
    5007           0 :             sig_pk = node2;
    5008           0 :             break;
    5009             :           }
    5010             : 
    5011           0 :       if (!sig_pk)
    5012           0 :         continue;
    5013             : 
    5014             :       /* Find the secret subkey that matches the public subkey */
    5015           0 :       log_debug ("FIXME: Check whether a secret subkey is available.\n");
    5016             :       /* if (!sub_sk) */
    5017             :       /*   { */
    5018             :       /*     tty_printf (_("no secret subkey for public subkey %s - ignoring\n"), */
    5019             :       /*              keystr_from_pk (sub_pk)); */
    5020             :       /*     continue; */
    5021             :       /*   } */
    5022             : 
    5023             : 
    5024             :       /* Now we can get to work.  */
    5025             : 
    5026           0 :       rc = make_backsig (sig_pk->pkt->pkt.signature, main_pk, sub_pk, sub_pk,
    5027             :                          timestamp, NULL);
    5028           0 :       if (!rc)
    5029             :         {
    5030             :           PKT_signature *newsig;
    5031             :           PACKET *newpkt;
    5032             : 
    5033           0 :           rc = update_keysig_packet (&newsig, sig_pk->pkt->pkt.signature,
    5034             :                                      main_pk, NULL, sub_pk, main_pk,
    5035             :                                      NULL, NULL);
    5036           0 :           if (!rc)
    5037             :             {
    5038             :               /* Put the new sig into place on the pubkey */
    5039           0 :               newpkt = xmalloc_clear (sizeof (*newpkt));
    5040           0 :               newpkt->pkttype = PKT_SIGNATURE;
    5041           0 :               newpkt->pkt.signature = newsig;
    5042           0 :               free_packet (sig_pk->pkt);
    5043           0 :               xfree (sig_pk->pkt);
    5044           0 :               sig_pk->pkt = newpkt;
    5045             : 
    5046           0 :               modified = 1;
    5047             :             }
    5048             :           else
    5049             :             {
    5050           0 :               log_error ("update_keysig_packet failed: %s\n",
    5051             :                          gpg_strerror (rc));
    5052           0 :               break;
    5053             :             }
    5054             :         }
    5055             :       else
    5056             :         {
    5057           0 :           log_error ("make_backsig failed: %s\n", gpg_strerror (rc));
    5058           0 :           break;
    5059             :         }
    5060             :     }
    5061             : 
    5062           0 :   return modified;
    5063             : }
    5064             : 
    5065             : 
    5066             : static int
    5067           0 : change_primary_uid_cb (PKT_signature * sig, void *opaque)
    5068             : {
    5069             :   byte buf[1];
    5070             : 
    5071             :   /* first clear all primary uid flags so that we are sure none are
    5072             :    * lingering around */
    5073           0 :   delete_sig_subpkt (sig->hashed, SIGSUBPKT_PRIMARY_UID);
    5074           0 :   delete_sig_subpkt (sig->unhashed, SIGSUBPKT_PRIMARY_UID);
    5075             : 
    5076             :   /* if opaque is set,we want to set the primary id */
    5077           0 :   if (opaque)
    5078             :     {
    5079           0 :       buf[0] = 1;
    5080           0 :       build_sig_subpkt (sig, SIGSUBPKT_PRIMARY_UID, buf, 1);
    5081             :     }
    5082             : 
    5083           0 :   return 0;
    5084             : }
    5085             : 
    5086             : 
    5087             : /*
    5088             :  * Set the primary uid flag for the selected UID.  We will also reset
    5089             :  * all other primary uid flags.  For this to work with have to update
    5090             :  * all the signature timestamps.  If we would do this with the current
    5091             :  * time, we lose quite a lot of information, so we use a a kludge to
    5092             :  * do this: Just increment the timestamp by one second which is
    5093             :  * sufficient to updated a signature during import.
    5094             :  */
    5095             : static int
    5096           0 : menu_set_primary_uid (KBNODE pub_keyblock)
    5097             : {
    5098             :   PKT_public_key *main_pk;
    5099             :   PKT_user_id *uid;
    5100             :   KBNODE node;
    5101             :   u32 keyid[2];
    5102             :   int selected;
    5103           0 :   int attribute = 0;
    5104           0 :   int modified = 0;
    5105             : 
    5106           0 :   if (count_selected_uids (pub_keyblock) != 1)
    5107             :     {
    5108           0 :       tty_printf (_("Please select exactly one user ID.\n"));
    5109           0 :       return 0;
    5110             :     }
    5111             : 
    5112           0 :   main_pk = NULL;
    5113           0 :   uid = NULL;
    5114           0 :   selected = 0;
    5115             : 
    5116             :   /* Is our selected uid an attribute packet? */
    5117           0 :   for (node = pub_keyblock; node; node = node->next)
    5118           0 :     if (node->pkt->pkttype == PKT_USER_ID && node->flag & NODFLG_SELUID)
    5119           0 :       attribute = (node->pkt->pkt.user_id->attrib_data != NULL);
    5120             : 
    5121           0 :   for (node = pub_keyblock; node; node = node->next)
    5122             :     {
    5123           0 :       if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
    5124           0 :         break; /* No more user ids expected - ready.  */
    5125             : 
    5126           0 :       if (node->pkt->pkttype == PKT_PUBLIC_KEY)
    5127             :         {
    5128           0 :           main_pk = node->pkt->pkt.public_key;
    5129           0 :           keyid_from_pk (main_pk, keyid);
    5130             :         }
    5131           0 :       else if (node->pkt->pkttype == PKT_USER_ID)
    5132             :         {
    5133           0 :           uid = node->pkt->pkt.user_id;
    5134           0 :           selected = node->flag & NODFLG_SELUID;
    5135             :         }
    5136           0 :       else if (main_pk && uid && node->pkt->pkttype == PKT_SIGNATURE)
    5137             :         {
    5138           0 :           PKT_signature *sig = node->pkt->pkt.signature;
    5139           0 :           if (keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
    5140           0 :               && (uid && (sig->sig_class & ~3) == 0x10)
    5141           0 :               && attribute == (uid->attrib_data != NULL)
    5142           0 :               && sig->flags.chosen_selfsig)
    5143             :             {
    5144           0 :               if (sig->version < 4)
    5145             :                 {
    5146           0 :                   char *user =
    5147           0 :                     utf8_to_native (uid->name, strlen (uid->name), 0);
    5148             : 
    5149           0 :                   log_info (_("skipping v3 self-signature on user ID \"%s\"\n"),
    5150             :                             user);
    5151           0 :                   xfree (user);
    5152             :                 }
    5153             :               else
    5154             :                 {
    5155             :                   /* This is a selfsignature which is to be replaced.
    5156             :                      We can just ignore v3 signatures because they are
    5157             :                      not able to carry the primary ID flag.  We also
    5158             :                      ignore self-sigs on user IDs that are not of the
    5159             :                      same type that we are making primary.  That is, if
    5160             :                      we are making a user ID primary, we alter user IDs.
    5161             :                      If we are making an attribute packet primary, we
    5162             :                      alter attribute packets. */
    5163             : 
    5164             :                   /* FIXME: We must make sure that we only have one
    5165             :                      self-signature per user ID here (not counting
    5166             :                      revocations) */
    5167             :                   PKT_signature *newsig;
    5168             :                   PACKET *newpkt;
    5169             :                   const byte *p;
    5170             :                   int action;
    5171             : 
    5172             :                   /* See whether this signature has the primary UID flag.  */
    5173           0 :                   p = parse_sig_subpkt (sig->hashed,
    5174             :                                         SIGSUBPKT_PRIMARY_UID, NULL);
    5175           0 :                   if (!p)
    5176           0 :                     p = parse_sig_subpkt (sig->unhashed,
    5177             :                                           SIGSUBPKT_PRIMARY_UID, NULL);
    5178           0 :                   if (p && *p)  /* yes */
    5179           0 :                     action = selected ? 0 : -1;
    5180             :                   else          /* no */
    5181           0 :                     action = selected ? 1 : 0;
    5182             : 
    5183           0 :                   if (action)
    5184             :                     {
    5185           0 :                       int rc = update_keysig_packet (&newsig, sig,
    5186             :                                                      main_pk, uid, NULL,
    5187             :                                                      main_pk,
    5188             :                                                      change_primary_uid_cb,
    5189             :                                                      action > 0 ? "x" : NULL);
    5190           0 :                       if (rc)
    5191             :                         {
    5192           0 :                           log_error ("update_keysig_packet failed: %s\n",
    5193             :                                      gpg_strerror (rc));
    5194           0 :                           return 0;
    5195             :                         }
    5196             :                       /* replace the packet */
    5197           0 :                       newpkt = xmalloc_clear (sizeof *newpkt);
    5198           0 :                       newpkt->pkttype = PKT_SIGNATURE;
    5199           0 :                       newpkt->pkt.signature = newsig;
    5200           0 :                       free_packet (node->pkt);
    5201           0 :                       xfree (node->pkt);
    5202           0 :                       node->pkt = newpkt;
    5203           0 :                       modified = 1;
    5204             :                     }
    5205             :                 }
    5206             :             }
    5207             :         }
    5208             :     }
    5209             : 
    5210           0 :   return modified;
    5211             : }
    5212             : 
    5213             : 
    5214             : /*
    5215             :  * Set preferences to new values for the selected user IDs
    5216             :  */
    5217             : static int
    5218           0 : menu_set_preferences (KBNODE pub_keyblock)
    5219             : {
    5220             :   PKT_public_key *main_pk;
    5221             :   PKT_user_id *uid;
    5222             :   KBNODE node;
    5223             :   u32 keyid[2];
    5224             :   int selected, select_all;
    5225           0 :   int modified = 0;
    5226             : 
    5227           0 :   no_primary_warning (pub_keyblock);
    5228             : 
    5229           0 :   select_all = !count_selected_uids (pub_keyblock);
    5230             : 
    5231             :   /* Now we can actually change the self signature(s) */
    5232           0 :   main_pk = NULL;
    5233           0 :   uid = NULL;
    5234           0 :   selected = 0;
    5235           0 :   for (node = pub_keyblock; node; node = node->next)
    5236             :     {
    5237           0 :       if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
    5238           0 :         break; /* No more user-ids expected - ready.  */
    5239             : 
    5240           0 :       if (node->pkt->pkttype == PKT_PUBLIC_KEY)
    5241             :         {
    5242           0 :           main_pk = node->pkt->pkt.public_key;
    5243           0 :           keyid_from_pk (main_pk, keyid);
    5244             :         }
    5245           0 :       else if (node->pkt->pkttype == PKT_USER_ID)
    5246             :         {
    5247           0 :           uid = node->pkt->pkt.user_id;
    5248           0 :           selected = select_all || (node->flag & NODFLG_SELUID);
    5249             :         }
    5250           0 :       else if (main_pk && uid && selected
    5251           0 :                && node->pkt->pkttype == PKT_SIGNATURE)
    5252             :         {
    5253           0 :           PKT_signature *sig = node->pkt->pkt.signature;
    5254           0 :           if (keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
    5255           0 :               && (uid && (sig->sig_class & ~3) == 0x10)
    5256           0 :               && sig->flags.chosen_selfsig)
    5257             :             {
    5258           0 :               if (sig->version < 4)
    5259             :                 {
    5260           0 :                   char *user =
    5261           0 :                     utf8_to_native (uid->name, strlen (uid->name), 0);
    5262             : 
    5263           0 :                   log_info (_("skipping v3 self-signature on user ID \"%s\"\n"),
    5264             :                             user);
    5265           0 :                   xfree (user);
    5266             :                 }
    5267             :               else
    5268             :                 {
    5269             :                   /* This is a selfsignature which is to be replaced
    5270             :                    * We have to ignore v3 signatures because they are
    5271             :                    * not able to carry the preferences.  */
    5272             :                   PKT_signature *newsig;
    5273             :                   PACKET *newpkt;
    5274             :                   int rc;
    5275             : 
    5276           0 :                   rc = update_keysig_packet (&newsig, sig,
    5277             :                                              main_pk, uid, NULL, main_pk,
    5278             :                                              keygen_upd_std_prefs, NULL);
    5279           0 :                   if (rc)
    5280             :                     {
    5281           0 :                       log_error ("update_keysig_packet failed: %s\n",
    5282             :                                  gpg_strerror (rc));
    5283           0 :                       return 0;
    5284             :                     }
    5285             :                   /* replace the packet */
    5286           0 :                   newpkt = xmalloc_clear (sizeof *newpkt);
    5287           0 :                   newpkt->pkttype = PKT_SIGNATURE;
    5288           0 :                   newpkt->pkt.signature = newsig;
    5289           0 :                   free_packet (node->pkt);
    5290           0 :                   xfree (node->pkt);
    5291           0 :                   node->pkt = newpkt;
    5292           0 :                   modified = 1;
    5293             :                 }
    5294             :             }
    5295             :         }
    5296             :     }
    5297             : 
    5298           0 :   return modified;
    5299             : }
    5300             : 
    5301             : 
    5302             : static int
    5303           0 : menu_set_keyserver_url (const char *url, KBNODE pub_keyblock)
    5304             : {
    5305             :   PKT_public_key *main_pk;
    5306             :   PKT_user_id *uid;
    5307             :   KBNODE node;
    5308             :   u32 keyid[2];
    5309             :   int selected, select_all;
    5310           0 :   int modified = 0;
    5311             :   char *answer, *uri;
    5312             : 
    5313           0 :   no_primary_warning (pub_keyblock);
    5314             : 
    5315           0 :   if (url)
    5316           0 :     answer = xstrdup (url);
    5317             :   else
    5318             :     {
    5319           0 :       answer = cpr_get_utf8 ("keyedit.add_keyserver",
    5320           0 :                              _("Enter your preferred keyserver URL: "));
    5321           0 :       if (answer[0] == '\0' || answer[0] == CONTROL_D)
    5322             :         {
    5323           0 :           xfree (answer);
    5324           0 :           return 0;
    5325             :         }
    5326             :     }
    5327             : 
    5328           0 :   if (ascii_strcasecmp (answer, "none") == 0)
    5329           0 :     uri = NULL;
    5330             :   else
    5331             :     {
    5332           0 :       struct keyserver_spec *keyserver = NULL;
    5333             :       /* Sanity check the format */
    5334           0 :       keyserver = parse_keyserver_uri (answer, 1);
    5335           0 :       xfree (answer);
    5336           0 :       if (!keyserver)
    5337             :         {
    5338           0 :           log_info (_("could not parse keyserver URL\n"));
    5339           0 :           return 0;
    5340             :         }
    5341           0 :       uri = xstrdup (keyserver->uri);
    5342           0 :       free_keyserver_spec (keyserver);
    5343             :     }
    5344             : 
    5345           0 :   select_all = !count_selected_uids (pub_keyblock);
    5346             : 
    5347             :   /* Now we can actually change the self signature(s) */
    5348           0 :   main_pk = NULL;
    5349           0 :   uid = NULL;
    5350           0 :   selected = 0;
    5351           0 :   for (node = pub_keyblock; node; node = node->next)
    5352             :     {
    5353           0 :       if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
    5354           0 :         break; /* ready */
    5355             : 
    5356           0 :       if (node->pkt->pkttype == PKT_PUBLIC_KEY)
    5357             :         {
    5358           0 :           main_pk = node->pkt->pkt.public_key;
    5359           0 :           keyid_from_pk (main_pk, keyid);
    5360             :         }
    5361           0 :       else if (node->pkt->pkttype == PKT_USER_ID)
    5362             :         {
    5363           0 :           uid = node->pkt->pkt.user_id;
    5364           0 :           selected = select_all || (node->flag & NODFLG_SELUID);
    5365             :         }
    5366           0 :       else if (main_pk && uid && selected
    5367           0 :                && node->pkt->pkttype == PKT_SIGNATURE)
    5368             :         {
    5369           0 :           PKT_signature *sig = node->pkt->pkt.signature;
    5370           0 :           if (keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
    5371           0 :               && (uid && (sig->sig_class & ~3) == 0x10)
    5372           0 :               && sig->flags.chosen_selfsig)
    5373             :             {
    5374           0 :               char *user = utf8_to_native (uid->name, strlen (uid->name), 0);
    5375           0 :               if (sig->version < 4)
    5376           0 :                 log_info (_("skipping v3 self-signature on user ID \"%s\"\n"),
    5377             :                           user);
    5378             :               else
    5379             :                 {
    5380             :                   /* This is a selfsignature which is to be replaced
    5381             :                    * We have to ignore v3 signatures because they are
    5382             :                    * not able to carry the subpacket. */
    5383             :                   PKT_signature *newsig;
    5384             :                   PACKET *newpkt;
    5385             :                   int rc;
    5386             :                   const byte *p;
    5387             :                   size_t plen;
    5388             : 
    5389           0 :                   p = parse_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_KS, &plen);
    5390           0 :                   if (p && plen)
    5391             :                     {
    5392           0 :                       tty_printf ("Current preferred keyserver for user"
    5393             :                                   " ID \"%s\": ", user);
    5394           0 :                       tty_print_utf8_string (p, plen);
    5395           0 :                       tty_printf ("\n");
    5396           0 :                       if (!cpr_get_answer_is_yes
    5397             :                           ("keyedit.confirm_keyserver",
    5398             :                            uri
    5399             :                            ? _("Are you sure you want to replace it? (y/N) ")
    5400             :                            : _("Are you sure you want to delete it? (y/N) ")))
    5401           0 :                         continue;
    5402             :                     }
    5403           0 :                   else if (uri == NULL)
    5404             :                     {
    5405             :                       /* There is no current keyserver URL, so there
    5406             :                          is no point in trying to un-set it. */
    5407           0 :                       continue;
    5408             :                     }
    5409             : 
    5410           0 :                   rc = update_keysig_packet (&newsig, sig,
    5411             :                                              main_pk, uid, NULL,
    5412             :                                              main_pk,
    5413             :                                              keygen_add_keyserver_url, uri);
    5414           0 :                   if (rc)
    5415             :                     {
    5416           0 :                       log_error ("update_keysig_packet failed: %s\n",
    5417             :                                  gpg_strerror (rc));
    5418           0 :                       xfree (uri);
    5419           0 :                       return 0;
    5420             :                     }
    5421             :                   /* replace the packet */
    5422           0 :                   newpkt = xmalloc_clear (sizeof *newpkt);
    5423           0 :                   newpkt->pkttype = PKT_SIGNATURE;
    5424           0 :                   newpkt->pkt.signature = newsig;
    5425           0 :                   free_packet (node->pkt);
    5426           0 :                   xfree (node->pkt);
    5427           0 :                   node->pkt = newpkt;
    5428           0 :                   modified = 1;
    5429             :                 }
    5430             : 
    5431           0 :               xfree (user);
    5432             :             }
    5433             :         }
    5434             :     }
    5435             : 
    5436           0 :   xfree (uri);
    5437           0 :   return modified;
    5438             : }
    5439             : 
    5440             : static int
    5441           0 : menu_set_notation (const char *string, KBNODE pub_keyblock)
    5442             : {
    5443             :   PKT_public_key *main_pk;
    5444             :   PKT_user_id *uid;
    5445             :   KBNODE node;
    5446             :   u32 keyid[2];
    5447             :   int selected, select_all;
    5448           0 :   int modified = 0;
    5449             :   char *answer;
    5450             :   struct notation *notation;
    5451             : 
    5452           0 :   no_primary_warning (pub_keyblock);
    5453             : 
    5454           0 :   if (string)
    5455           0 :     answer = xstrdup (string);
    5456             :   else
    5457             :     {
    5458           0 :       answer = cpr_get_utf8 ("keyedit.add_notation",
    5459           0 :                              _("Enter the notation: "));
    5460           0 :       if (answer[0] == '\0' || answer[0] == CONTROL_D)
    5461             :         {
    5462           0 :           xfree (answer);
    5463           0 :           return 0;
    5464             :         }
    5465             :     }
    5466             : 
    5467           0 :   if (!ascii_strcasecmp (answer, "none")
    5468           0 :       || !ascii_strcasecmp (answer, "-"))
    5469           0 :     notation = NULL; /* Delete them all.  */
    5470             :   else
    5471             :     {
    5472           0 :       notation = string_to_notation (answer, 0);
    5473           0 :       if (!notation)
    5474             :         {
    5475           0 :           xfree (answer);
    5476           0 :           return 0;
    5477             :         }
    5478             :     }
    5479             : 
    5480           0 :   xfree (answer);
    5481             : 
    5482           0 :   select_all = !count_selected_uids (pub_keyblock);
    5483             : 
    5484             :   /* Now we can actually change the self signature(s) */
    5485           0 :   main_pk = NULL;
    5486           0 :   uid = NULL;
    5487           0 :   selected = 0;
    5488           0 :   for (node = pub_keyblock; node; node = node->next)
    5489             :     {
    5490           0 :       if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
    5491           0 :         break; /* ready */
    5492             : 
    5493           0 :       if (node->pkt->pkttype == PKT_PUBLIC_KEY)
    5494             :         {
    5495           0 :           main_pk = node->pkt->pkt.public_key;
    5496           0 :           keyid_from_pk (main_pk, keyid);
    5497             :         }
    5498           0 :       else if (node->pkt->pkttype == PKT_USER_ID)
    5499             :         {
    5500           0 :           uid = node->pkt->pkt.user_id;
    5501           0 :           selected = select_all || (node->flag & NODFLG_SELUID);
    5502             :         }
    5503           0 :       else if (main_pk && uid && selected
    5504           0 :                && node->pkt->pkttype == PKT_SIGNATURE)
    5505             :         {
    5506           0 :           PKT_signature *sig = node->pkt->pkt.signature;
    5507           0 :           if (keyid[0] == sig->keyid[0] && keyid[1] == sig->keyid[1]
    5508           0 :               && (uid && (sig->sig_class & ~3) == 0x10)
    5509           0 :               && sig->flags.chosen_selfsig)
    5510             :             {
    5511           0 :               char *user = utf8_to_native (uid->name, strlen (uid->name), 0);
    5512           0 :               if (sig->version < 4)
    5513           0 :                 log_info (_("skipping v3 self-signature on user ID \"%s\"\n"),
    5514             :                           user);
    5515             :               else
    5516             :                 {
    5517             :                   PKT_signature *newsig;
    5518             :                   PACKET *newpkt;
    5519           0 :                   int rc, skip = 0, addonly = 1;
    5520             : 
    5521           0 :                   if (sig->flags.notation)
    5522             :                     {
    5523           0 :                       tty_printf ("Current notations for user ID \"%s\":\n",
    5524             :                                   user);
    5525           0 :                       tty_print_notations (-9, sig);
    5526             :                     }
    5527             :                   else
    5528             :                     {
    5529           0 :                       tty_printf ("No notations on user ID \"%s\"\n", user);
    5530           0 :                       if (notation == NULL)
    5531             :                         {
    5532             :                           /* There are no current notations, so there
    5533             :                              is no point in trying to un-set them. */
    5534           0 :                           continue;
    5535             :                         }
    5536             :                     }
    5537             : 
    5538           0 :                   if (notation)
    5539             :                     {
    5540             :                       struct notation *n;
    5541           0 :                       int deleting = 0;
    5542             : 
    5543           0 :                       notation->next = sig_to_notation (sig);
    5544             : 
    5545           0 :                       for (n = notation->next; n; n = n->next)
    5546           0 :                         if (strcmp (n->name, notation->name) == 0)
    5547             :                           {
    5548           0 :                             if (notation->value)
    5549             :                               {
    5550           0 :                                 if (strcmp (n->value, notation->value) == 0)
    5551             :                                   {
    5552           0 :                                     if (notation->flags.ignore)
    5553             :                                       {
    5554             :                                         /* Value match with a delete
    5555             :                                            flag. */
    5556           0 :                                         n->flags.ignore = 1;
    5557           0 :                                         deleting = 1;
    5558             :                                       }
    5559             :                                     else
    5560             :                                       {
    5561             :                                         /* Adding the same notation
    5562             :                                            twice, so don't add it at
    5563             :                                            all. */
    5564           0 :                                         skip = 1;
    5565           0 :                                         tty_printf ("Skipping notation:"
    5566             :                                                     " %s=%s\n",
    5567             :                                                     notation->name,
    5568             :                                                     notation->value);
    5569           0 :                                         break;
    5570             :                                       }
    5571             :                                   }
    5572             :                               }
    5573             :                             else
    5574             :                               {
    5575             :                                 /* No value, so it means delete. */
    5576           0 :                                 n->flags.ignore = 1;
    5577           0 :                                 deleting = 1;
    5578             :                               }
    5579             : 
    5580           0 :                             if (n->flags.ignore)
    5581             :                               {
    5582           0 :                                 tty_printf ("Removing notation: %s=%s\n",
    5583             :                                             n->name, n->value);
    5584           0 :                                 addonly = 0;
    5585             :                               }
    5586             :                           }
    5587             : 
    5588           0 :                       if (!notation->flags.ignore && !skip)
    5589           0 :                         tty_printf ("Adding notation: %s=%s\n",
    5590             :                                     notation->name, notation->value);
    5591             : 
    5592             :                       /* We tried to delete, but had no matches.  */
    5593           0 :                       if (notation->flags.ignore && !deleting)
    5594           0 :                         continue;
    5595             :                     }
    5596             :                   else
    5597             :                     {
    5598           0 :                       tty_printf ("Removing all notations\n");
    5599           0 :                       addonly = 0;
    5600             :                     }
    5601             : 
    5602           0 :                   if (skip
    5603           0 :                       || (!addonly
    5604           0 :                           &&
    5605           0 :                           !cpr_get_answer_is_yes ("keyedit.confirm_notation",
    5606           0 :                                                   _("Proceed? (y/N) "))))
    5607           0 :                     continue;
    5608             : 
    5609           0 :                   rc = update_keysig_packet (&newsig, sig,
    5610             :                                              main_pk, uid, NULL,
    5611             :                                              main_pk,
    5612             :                                              keygen_add_notations, notation);
    5613           0 :                   if (rc)
    5614             :                     {
    5615           0 :                       log_error ("update_keysig_packet failed: %s\n",
    5616             :                                  gpg_strerror (rc));
    5617           0 :                       free_notation (notation);
    5618           0 :                       xfree (user);
    5619           0 :                       return 0;
    5620             :                     }
    5621             : 
    5622             :                   /* replace the packet */
    5623           0 :                   newpkt = xmalloc_clear (sizeof *newpkt);
    5624           0 :                   newpkt->pkttype = PKT_SIGNATURE;
    5625           0 :                   newpkt->pkt.signature = newsig;
    5626           0 :                   free_packet (node->pkt);
    5627           0 :                   xfree (node->pkt);
    5628           0 :                   node->pkt = newpkt;
    5629           0 :                   modified = 1;
    5630             : 
    5631           0 :                   if (notation)
    5632             :                     {
    5633             :                       /* Snip off the notation list from the sig */
    5634           0 :                       free_notation (notation->next);
    5635           0 :                       notation->next = NULL;
    5636             :                     }
    5637             : 
    5638           0 :                   xfree (user);
    5639             :                 }
    5640             :             }
    5641             :         }
    5642             :     }
    5643             : 
    5644           0 :   free_notation (notation);
    5645           0 :   return modified;
    5646             : }
    5647             : 
    5648             : 
    5649             : /*
    5650             :  * Select one user id or remove all selection if IDX is 0 or select
    5651             :  * all if IDX is -1.  Returns: True if the selection changed.
    5652             :  */
    5653             : static int
    5654           0 : menu_select_uid (KBNODE keyblock, int idx)
    5655             : {
    5656             :   KBNODE node;
    5657             :   int i;
    5658             : 
    5659           0 :   if (idx == -1)                /* Select all. */
    5660             :     {
    5661           0 :       for (node = keyblock; node; node = node->next)
    5662           0 :         if (node->pkt->pkttype == PKT_USER_ID)
    5663           0 :           node->flag |= NODFLG_SELUID;
    5664           0 :       return 1;
    5665             :     }
    5666           0 :   else if (idx)                 /* Toggle.  */
    5667             :     {
    5668           0 :       for (i = 0, node = keyblock; node; node = node->next)
    5669             :         {
    5670           0 :           if (node->pkt->pkttype == PKT_USER_ID)
    5671           0 :             if (++i == idx)
    5672           0 :               break;
    5673             :         }
    5674           0 :       if (!node)
    5675             :         {
    5676           0 :           tty_printf (_("No user ID with index %d\n"), idx);
    5677           0 :           return 0;
    5678             :         }
    5679             : 
    5680           0 :       for (i = 0, node = keyblock; node; node = node->next)
    5681             :         {
    5682           0 :           if (node->pkt->pkttype == PKT_USER_ID)
    5683             :             {
    5684           0 :               if (++i == idx)
    5685             :                 {
    5686           0 :                   if ((node->flag & NODFLG_SELUID))
    5687           0 :                     node->flag &= ~NODFLG_SELUID;
    5688             :                   else
    5689           0 :                     node->flag |= NODFLG_SELUID;
    5690             :                 }
    5691             :             }
    5692             :         }
    5693             :     }
    5694             :   else                          /* Unselect all */
    5695             :     {
    5696           0 :       for (node = keyblock; node; node = node->next)
    5697           0 :         if (node->pkt->pkttype == PKT_USER_ID)
    5698           0 :           node->flag &= ~NODFLG_SELUID;
    5699             :     }
    5700             : 
    5701           0 :   return 1;
    5702             : }
    5703             : 
    5704             : 
    5705             : /* Search in the keyblock for a uid that matches namehash */
    5706             : static int
    5707           0 : menu_select_uid_namehash (KBNODE keyblock, const char *namehash)
    5708             : {
    5709             :   byte hash[NAMEHASH_LEN];
    5710             :   KBNODE node;
    5711             :   int i;
    5712             : 
    5713           0 :   log_assert (strlen (namehash) == NAMEHASH_LEN * 2);
    5714             : 
    5715           0 :   for (i = 0; i < NAMEHASH_LEN; i++)
    5716           0 :     hash[i] = hextobyte (&namehash[i * 2]);
    5717             : 
    5718           0 :   for (node = keyblock->next; node; node = node->next)
    5719             :     {
    5720           0 :       if (node->pkt->pkttype == PKT_USER_ID)
    5721             :         {
    5722           0 :           namehash_from_uid (node->pkt->pkt.user_id);
    5723           0 :           if (memcmp (node->pkt->pkt.user_id->namehash, hash, NAMEHASH_LEN) ==
    5724             :               0)
    5725             :             {
    5726           0 :               if (node->flag & NODFLG_SELUID)
    5727           0 :                 node->flag &= ~NODFLG_SELUID;
    5728             :               else
    5729           0 :                 node->flag |= NODFLG_SELUID;
    5730             : 
    5731           0 :               break;
    5732             :             }
    5733             :         }
    5734             :     }
    5735             : 
    5736           0 :   if (!node)
    5737             :     {
    5738           0 :       tty_printf (_("No user ID with hash %s\n"), namehash);
    5739           0 :       return 0;
    5740             :     }
    5741             : 
    5742           0 :   return 1;
    5743             : }
    5744             : 
    5745             : 
    5746             : /*
    5747             :  * Select secondary keys
    5748             :  * Returns: True if the selection changed.
    5749             :  */
    5750             : static int
    5751           0 : menu_select_key (KBNODE keyblock, int idx, char *p)
    5752             : {
    5753             :   KBNODE node;
    5754             :   int i, j;
    5755             :   int is_hex_digits;
    5756             : 
    5757           0 :   is_hex_digits = p && strlen (p) >= 8;
    5758           0 :   if (is_hex_digits)
    5759             :     {
    5760             :       /* Skip initial spaces.  */
    5761           0 :       while (spacep (p))
    5762           0 :         p ++;
    5763             :       /* If the id starts with 0x accept and ignore it.  */
    5764           0 :       if (p[0] == '0' && p[1] == 'x')
    5765           0 :         p += 2;
    5766             : 
    5767           0 :       for (i = 0, j = 0; p[i]; i ++)
    5768           0 :         if (hexdigitp (&p[i]))
    5769             :           {
    5770           0 :             p[j] = toupper (p[i]);
    5771           0 :             j ++;
    5772             :           }
    5773           0 :         else if (spacep (&p[i]))
    5774             :           /* Skip spaces.  */
    5775             :           {
    5776             :           }
    5777             :         else
    5778             :           {
    5779           0 :             is_hex_digits = 0;
    5780           0 :             break;
    5781             :           }
    5782           0 :       if (is_hex_digits)
    5783             :         /* In case we skipped some spaces, add a new NUL terminator.  */
    5784             :         {
    5785           0 :           p[j] = 0;
    5786             :           /* If we skipped some spaces, make sure that we still have
    5787             :              at least 8 characters.  */
    5788           0 :           is_hex_digits = (/* Short keyid.  */
    5789           0 :                            strlen (p) == 8
    5790             :                            /* Long keyid.  */
    5791           0 :                            || strlen (p) == 16
    5792             :                            /* Fingerprints are (currently) 32 or 40
    5793             :                               characters.  */
    5794           0 :                            || strlen (p) >= 32);
    5795             :         }
    5796             :     }
    5797             : 
    5798           0 :   if (is_hex_digits)
    5799             :     {
    5800           0 :       int found_one = 0;
    5801           0 :       for (node = keyblock; node; node = node->next)
    5802           0 :         if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
    5803           0 :             || node->pkt->pkttype == PKT_SECRET_SUBKEY)
    5804             :           {
    5805           0 :             int match = 0;
    5806           0 :             if (strlen (p) == 8 || strlen (p) == 16)
    5807           0 :               {
    5808             :                 u32 kid[2];
    5809             :                 char kid_str[17];
    5810           0 :                 keyid_from_pk (node->pkt->pkt.public_key, kid);
    5811           0 :                 format_keyid (kid, strlen (p) == 8 ? KF_SHORT : KF_LONG,
    5812             :                               kid_str, sizeof (kid_str));
    5813             : 
    5814           0 :                 if (strcmp (p, kid_str) == 0)
    5815           0 :                   match = 1;
    5816             :               }
    5817             :             else
    5818             :               {
    5819             :                 char fp[2*MAX_FINGERPRINT_LEN + 1];
    5820           0 :                 hexfingerprint (node->pkt->pkt.public_key, fp, sizeof (fp));
    5821           0 :                 if (strcmp (fp, p) == 0)
    5822           0 :                   match = 1;
    5823             :               }
    5824             : 
    5825           0 :             if (match)
    5826             :               {
    5827           0 :                 if ((node->flag & NODFLG_SELKEY))
    5828           0 :                   node->flag &= ~NODFLG_SELKEY;
    5829             :                 else
    5830           0 :                   node->flag |= NODFLG_SELKEY;
    5831             : 
    5832           0 :                 found_one = 1;
    5833             :               }
    5834             :           }
    5835             : 
    5836           0 :       if (found_one)
    5837           0 :         return 1;
    5838             : 
    5839           0 :       tty_printf (_("No subkey with key ID '%s'.\n"), p);
    5840           0 :       return 0;
    5841             :     }
    5842             : 
    5843           0 :   if (idx == -1)                /* Select all.  */
    5844             :     {
    5845           0 :       for (node = keyblock; node; node = node->next)
    5846           0 :         if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
    5847           0 :             || node->pkt->pkttype == PKT_SECRET_SUBKEY)
    5848           0 :           node->flag |= NODFLG_SELKEY;
    5849             :     }
    5850           0 :   else if (idx)                 /* Toggle selection.  */
    5851             :     {
    5852           0 :       for (i = 0, node = keyblock; node; node = node->next)
    5853             :         {
    5854           0 :           if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
    5855           0 :               || node->pkt->pkttype == PKT_SECRET_SUBKEY)
    5856           0 :             if (++i == idx)
    5857           0 :               break;
    5858             :         }
    5859           0 :       if (!node)
    5860             :         {
    5861           0 :           tty_printf (_("No subkey with index %d\n"), idx);
    5862           0 :           return 0;
    5863             :         }
    5864             : 
    5865           0 :       for (i = 0, node = keyblock; node; node = node->next)
    5866             :         {
    5867           0 :           if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
    5868           0 :               || node->pkt->pkttype == PKT_SECRET_SUBKEY)
    5869           0 :             if (++i == idx)
    5870             :               {
    5871           0 :                 if ((node->flag & NODFLG_SELKEY))
    5872           0 :                   node->flag &= ~NODFLG_SELKEY;
    5873             :                 else
    5874           0 :                   node->flag |= NODFLG_SELKEY;
    5875             :               }
    5876             :         }
    5877             :     }
    5878             :   else                          /* Unselect all. */
    5879             :     {
    5880           0 :       for (node = keyblock; node; node = node->next)
    5881           0 :         if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
    5882           0 :             || node->pkt->pkttype == PKT_SECRET_SUBKEY)
    5883           0 :           node->flag &= ~NODFLG_SELKEY;
    5884             :     }
    5885             : 
    5886           0 :   return 1;
    5887             : }
    5888             : 
    5889             : 
    5890             : static int
    5891           0 : count_uids_with_flag (KBNODE keyblock, unsigned flag)
    5892             : {
    5893             :   KBNODE node;
    5894           0 :   int i = 0;
    5895             : 
    5896           0 :   for (node = keyblock; node; node = node->next)
    5897           0 :     if (node->pkt->pkttype == PKT_USER_ID && (node->flag & flag))
    5898           0 :       i++;
    5899           0 :   return i;
    5900             : }
    5901             : 
    5902             : 
    5903             : static int
    5904           0 : count_keys_with_flag (KBNODE keyblock, unsigned flag)
    5905             : {
    5906             :   KBNODE node;
    5907           0 :   int i = 0;
    5908             : 
    5909           0 :   for (node = keyblock; node; node = node->next)
    5910           0 :     if ((node->pkt->pkttype == PKT_PUBLIC_SUBKEY
    5911           0 :          || node->pkt->pkttype == PKT_SECRET_SUBKEY) && (node->flag & flag))
    5912           0 :       i++;
    5913           0 :   return i;
    5914             : }
    5915             : 
    5916             : 
    5917             : static int
    5918           0 : count_uids (KBNODE keyblock)
    5919             : {
    5920             :   KBNODE node;
    5921           0 :   int i = 0;
    5922             : 
    5923           0 :   for (node = keyblock; node; node = node->next)
    5924           0 :     if (node->pkt->pkttype == PKT_USER_ID)
    5925           0 :       i++;
    5926           0 :   return i;
    5927             : }
    5928             : 
    5929             : 
    5930             : /*
    5931             :  * Returns true if there is at least one selected user id
    5932             :  */
    5933             : static int
    5934           0 : count_selected_uids (KBNODE keyblock)
    5935             : {
    5936           0 :   return count_uids_with_flag (keyblock, NODFLG_SELUID);
    5937             : }
    5938             : 
    5939             : 
    5940             : static int
    5941           0 : count_selected_keys (KBNODE keyblock)
    5942             : {
    5943           0 :   return count_keys_with_flag (keyblock, NODFLG_SELKEY);
    5944             : }
    5945             : 
    5946             : 
    5947             : /* Returns how many real (i.e. not attribute) uids are unmarked.  */
    5948             : static int
    5949           0 : real_uids_left (KBNODE keyblock)
    5950             : {
    5951             :   KBNODE node;
    5952           0 :   int real = 0;
    5953             : 
    5954           0 :   for (node = keyblock; node; node = node->next)
    5955           0 :     if (node->pkt->pkttype == PKT_USER_ID && !(node->flag & NODFLG_SELUID) &&
    5956           0 :         !node->pkt->pkt.user_id->attrib_data)
    5957           0 :       real++;
    5958             : 
    5959           0 :   return real;
    5960             : }
    5961             : 
    5962             : 
    5963             : /*
    5964             :  * Ask whether the signature should be revoked.  If the user commits this,
    5965             :  * flag bit MARK_A is set on the signature and the user ID.
    5966             :  */
    5967             : static void
    5968           0 : ask_revoke_sig (KBNODE keyblock, KBNODE node)
    5969             : {
    5970           0 :   int doit = 0;
    5971             :   PKT_user_id *uid;
    5972           0 :   PKT_signature *sig = node->pkt->pkt.signature;
    5973           0 :   KBNODE unode = find_prev_kbnode (keyblock, node, PKT_USER_ID);
    5974             : 
    5975           0 :   if (!unode)
    5976             :     {
    5977           0 :       log_error ("Oops: no user ID for signature\n");
    5978           0 :       return;
    5979             :     }
    5980             : 
    5981           0 :   uid = unode->pkt->pkt.user_id;
    5982             : 
    5983           0 :   if (opt.with_colons)
    5984             :     {
    5985           0 :       if (uid->attrib_data)
    5986           0 :         printf ("uat:::::::::%u %lu", uid->numattribs, uid->attrib_len);
    5987             :       else
    5988             :         {
    5989           0 :           es_printf ("uid:::::::::");
    5990           0 :           es_write_sanitized (es_stdout, uid->name, uid->len, ":", NULL);
    5991             :         }
    5992             : 
    5993           0 :       es_printf ("\n");
    5994             : 
    5995           0 :       print_and_check_one_sig_colon (keyblock, node, NULL, NULL, NULL, NULL,
    5996             :                                      1);
    5997             :     }
    5998             :   else
    5999             :     {
    6000           0 :       char *p = utf8_to_native (unode->pkt->pkt.user_id->name,
    6001           0 :                                 unode->pkt->pkt.user_id->len, 0);
    6002           0 :       tty_printf (_("user ID: \"%s\"\n"), p);
    6003           0 :       xfree (p);
    6004             : 
    6005           0 :       tty_printf (_("signed by your key %s on %s%s%s\n"),
    6006           0 :                   keystr (sig->keyid), datestr_from_sig (sig),
    6007           0 :                   sig->flags.exportable ? "" : _(" (non-exportable)"), "");
    6008             :     }
    6009           0 :   if (sig->flags.expired)
    6010             :     {
    6011           0 :       tty_printf (_("This signature expired on %s.\n"),
    6012             :                   expirestr_from_sig (sig));
    6013             :       /* Use a different question so we can have different help text */
    6014           0 :       doit = cpr_get_answer_is_yes
    6015             :         ("ask_revoke_sig.expired",
    6016           0 :          _("Are you sure you still want to revoke it? (y/N) "));
    6017             :     }
    6018             :   else
    6019           0 :     doit = cpr_get_answer_is_yes
    6020             :       ("ask_revoke_sig.one",
    6021           0 :        _("Create a revocation certificate for this signature? (y/N) "));
    6022             : 
    6023           0 :   if (doit)
    6024             :     {
    6025           0 :       node->flag |= NODFLG_MARK_A;
    6026           0 :       unode->flag |= NODFLG_MARK_A;
    6027             :     }
    6028             : }
    6029             : 
    6030             : 
    6031             : /*
    6032             :  * Display all user ids of the current public key together with signatures
    6033             :  * done by one of our keys.  Then walk over all this sigs and ask the user
    6034             :  * whether he wants to revoke this signature.
    6035             :  * Return: True when the keyblock has changed.
    6036             :  */
    6037             : static int
    6038           0 : menu_revsig (KBNODE keyblock)
    6039             : {
    6040             :   PKT_signature *sig;
    6041             :   PKT_public_key *primary_pk;
    6042             :   KBNODE node;
    6043           0 :   int changed = 0;
    6044           0 :   int rc, any, skip = 1, all = !count_selected_uids (keyblock);
    6045           0 :   struct revocation_reason_info *reason = NULL;
    6046             : 
    6047           0 :   log_assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY);
    6048             : 
    6049             :   /* First check whether we have any signatures at all.  */
    6050           0 :   any = 0;
    6051           0 :   for (node = keyblock; node; node = node->next)
    6052             :     {
    6053           0 :       node->flag &= ~(NODFLG_SELSIG | NODFLG_MARK_A);
    6054           0 :       if (node->pkt->pkttype == PKT_USER_ID)
    6055             :         {
    6056           0 :           if (node->flag & NODFLG_SELUID || all)
    6057           0 :             skip = 0;
    6058             :           else
    6059           0 :             skip = 1;
    6060             :         }
    6061           0 :       else if (!skip && node->pkt->pkttype == PKT_SIGNATURE
    6062           0 :                && ((sig = node->pkt->pkt.signature),
    6063           0 :                    have_secret_key_with_kid (sig->keyid)))
    6064             :         {
    6065           0 :           if ((sig->sig_class & ~3) == 0x10)
    6066             :             {
    6067           0 :               any = 1;
    6068           0 :               break;
    6069             :             }
    6070             :         }
    6071             :     }
    6072             : 
    6073           0 :   if (!any)
    6074             :     {
    6075           0 :       tty_printf (_("Not signed by you.\n"));
    6076           0 :       return 0;
    6077             :     }
    6078             : 
    6079             : 
    6080             :   /* FIXME: detect duplicates here  */
    6081           0 :   tty_printf (_("You have signed these user IDs on key %s:\n"),
    6082           0 :               keystr_from_pk (keyblock->pkt->pkt.public_key));
    6083           0 :   for (node = keyblock; node; node = node->next)
    6084             :     {
    6085           0 :       node->flag &= ~(NODFLG_SELSIG | NODFLG_MARK_A);
    6086           0 :       if (node->pkt->pkttype == PKT_USER_ID)
    6087             :         {
    6088           0 :           if (node->flag & NODFLG_SELUID || all)
    6089           0 :             {
    6090           0 :               PKT_user_id *uid = node->pkt->pkt.user_id;
    6091             :               /* Hmmm: Should we show only UIDs with a signature? */
    6092           0 :               tty_printf ("     ");
    6093           0 :               tty_print_utf8_string (uid->name, uid->len);
    6094           0 :               tty_printf ("\n");
    6095           0 :               skip = 0;
    6096             :             }
    6097             :           else
    6098           0 :             skip = 1;
    6099             :         }
    6100           0 :       else if (!skip && node->pkt->pkttype == PKT_SIGNATURE
    6101           0 :                && ((sig = node->pkt->pkt.signature),
    6102           0 :                    have_secret_key_with_kid (sig->keyid)))
    6103             :         {
    6104           0 :           if ((sig->sig_class & ~3) == 0x10)
    6105             :             {
    6106           0 :               tty_printf ("   ");
    6107           0 :               tty_printf (_("signed by your key %s on %s%s%s\n"),
    6108           0 :                           keystr (sig->keyid), datestr_from_sig (sig),
    6109           0 :                           sig->flags.exportable ? "" : _(" (non-exportable)"),
    6110           0 :                           sig->flags.revocable ? "" : _(" (non-revocable)"));
    6111           0 :               if (sig->flags.revocable)
    6112           0 :                 node->flag |= NODFLG_SELSIG;
    6113             :             }
    6114           0 :           else if (sig->sig_class == 0x30)
    6115             :             {
    6116           0 :               tty_printf ("   ");
    6117           0 :               tty_printf (_("revoked by your key %s on %s\n"),
    6118           0 :                           keystr (sig->keyid), datestr_from_sig (sig));
    6119             :             }
    6120             :         }
    6121             :     }
    6122             : 
    6123           0 :   tty_printf ("\n");
    6124             : 
    6125             :   /* ask */
    6126           0 :   for (node = keyblock; node; node = node->next)
    6127             :     {
    6128           0 :       if (!(node->flag & NODFLG_SELSIG))
    6129           0 :         continue;
    6130           0 :       ask_revoke_sig (keyblock, node);
    6131             :     }
    6132             : 
    6133             :   /* present selected */
    6134           0 :   any = 0;
    6135           0 :   for (node = keyblock; node; node = node->next)
    6136             :     {
    6137           0 :       if (!(node->flag & NODFLG_MARK_A))
    6138           0 :         continue;
    6139           0 :       if (!any)
    6140             :         {
    6141           0 :           any = 1;
    6142           0 :           tty_printf (_("You are about to revoke these signatures:\n"));
    6143             :         }
    6144           0 :       if (node->pkt->pkttype == PKT_USER_ID)
    6145             :         {
    6146           0 :           PKT_user_id *uid = node->pkt->pkt.user_id;
    6147           0 :           tty_printf ("     ");
    6148           0 :           tty_print_utf8_string (uid->name, uid->len);
    6149           0 :           tty_printf ("\n");
    6150             :         }
    6151           0 :       else if (node->pkt->pkttype == PKT_SIGNATURE)
    6152             :         {
    6153           0 :           sig = node->pkt->pkt.signature;
    6154           0 :           tty_printf ("   ");
    6155           0 :           tty_printf (_("signed by your key %s on %s%s%s\n"),
    6156           0 :                       keystr (sig->keyid), datestr_from_sig (sig), "",
    6157           0 :                       sig->flags.exportable ? "" : _(" (non-exportable)"));
    6158             :         }
    6159             :     }
    6160           0 :   if (!any)
    6161           0 :     return 0;                   /* none selected */
    6162             : 
    6163           0 :   if (!cpr_get_answer_is_yes
    6164             :       ("ask_revoke_sig.okay",
    6165           0 :        _("Really create the revocation certificates? (y/N) ")))
    6166           0 :     return 0;                   /* forget it */
    6167             : 
    6168           0 :   reason = ask_revocation_reason (0, 1, 0);
    6169           0 :   if (!reason)
    6170             :     {                           /* user decided to cancel */
    6171           0 :       return 0;
    6172             :     }
    6173             : 
    6174             :   /* now we can sign the user ids */
    6175             : reloop:                 /* (must use this, because we are modifing the list) */
    6176           0 :   primary_pk = keyblock->pkt->pkt.public_key;
    6177           0 :   for (node = keyblock; node; node = node->next)
    6178             :     {
    6179             :       KBNODE unode;
    6180             :       PACKET *pkt;
    6181             :       struct sign_attrib attrib;
    6182             :       PKT_public_key *signerkey;
    6183             : 
    6184           0 :       if (!(node->flag & NODFLG_MARK_A)
    6185           0 :           || node->pkt->pkttype != PKT_SIGNATURE)
    6186           0 :         continue;
    6187           0 :       unode = find_prev_kbnode (keyblock, node, PKT_USER_ID);
    6188           0 :       log_assert (unode); /* we already checked this */
    6189             : 
    6190           0 :       memset (&attrib, 0, sizeof attrib);
    6191           0 :       attrib.reason = reason;
    6192           0 :       attrib.non_exportable = !node->pkt->pkt.signature->flags.exportable;
    6193             : 
    6194           0 :       node->flag &= ~NODFLG_MARK_A;
    6195           0 :       signerkey = xmalloc_secure_clear (sizeof *signerkey);
    6196           0 :       if (get_seckey (signerkey, node->pkt->pkt.signature->keyid))
    6197             :         {
    6198           0 :           log_info (_("no secret key\n"));
    6199           0 :           free_public_key (signerkey);
    6200           0 :           continue;
    6201             :         }
    6202           0 :       rc = make_keysig_packet (&sig, primary_pk,
    6203           0 :                                unode->pkt->pkt.user_id,
    6204             :                                NULL, signerkey, 0x30, 0, 0, 0,
    6205             :                                sign_mk_attrib, &attrib, NULL);
    6206           0 :       free_public_key (signerkey);
    6207           0 :       if (rc)
    6208             :         {
    6209           0 :           write_status_error ("keysig", rc);
    6210           0 :           log_error (_("signing failed: %s\n"), gpg_strerror (rc));
    6211           0 :           release_revocation_reason_info (reason);
    6212           0 :           return changed;
    6213             :         }
    6214           0 :       changed = 1;              /* we changed the keyblock */
    6215           0 :       update_trust = 1;
    6216             :       /* Are we revoking our own uid? */
    6217           0 :       if (primary_pk->keyid[0] == sig->keyid[0] &&
    6218           0 :           primary_pk->keyid[1] == sig->keyid[1])
    6219           0 :         unode->pkt->pkt.user_id->is_revoked = 1;
    6220           0 :       pkt = xmalloc_clear (sizeof *pkt);
    6221           0 :       pkt->pkttype = PKT_SIGNATURE;
    6222           0 :       pkt->pkt.signature = sig;
    6223           0 :       insert_kbnode (unode, new_kbnode (pkt), 0);
    6224           0 :       goto reloop;
    6225             :     }
    6226             : 
    6227           0 :   release_revocation_reason_info (reason);
    6228           0 :   return changed;
    6229             : }
    6230             : 
    6231             : 
    6232             : /* return 0 if revocation of NODE (which must be a User ID) was
    6233             :    successful, non-zero if there was an error.  *modified will be set
    6234             :    to 1 if a change was made. */
    6235             : static int
    6236           1 : core_revuid (ctrl_t ctrl, kbnode_t keyblock, KBNODE node,
    6237             :              const struct revocation_reason_info *reason, int *modified)
    6238             : {
    6239           1 :   PKT_public_key *pk = keyblock->pkt->pkt.public_key;
    6240             :   gpg_error_t rc;
    6241             : 
    6242           1 :   if (node->pkt->pkttype != PKT_USER_ID)
    6243             :     {
    6244           0 :       rc = gpg_error (GPG_ERR_NO_USER_ID);
    6245           0 :       write_status_error ("keysig", rc);
    6246           0 :       log_error (_("tried to revoke a non-user ID: %s\n"), gpg_strerror (rc));
    6247           0 :       return 1;
    6248             :     }
    6249             :   else
    6250             :     {
    6251           1 :       PKT_user_id *uid = node->pkt->pkt.user_id;
    6252             : 
    6253           1 :       if (uid->is_revoked)
    6254             :         {
    6255           0 :           char *user = utf8_to_native (uid->name, uid->len, 0);
    6256           0 :           log_info (_("user ID \"%s\" is already revoked\n"), user);
    6257           0 :           xfree (user);
    6258             :         }
    6259             :       else
    6260             :         {
    6261             :           PACKET *pkt;
    6262             :           PKT_signature *sig;
    6263             :           struct sign_attrib attrib;
    6264           1 :           u32 timestamp = make_timestamp ();
    6265             : 
    6266           1 :           if (uid->created >= timestamp)
    6267             :             {
    6268             :               /* Okay, this is a problem.  The user ID selfsig was
    6269             :                  created in the future, so we need to warn the user and
    6270             :                  set our revocation timestamp one second after that so
    6271             :                  everything comes out clean. */
    6272             : 
    6273           0 :               log_info (_("WARNING: a user ID signature is dated %d"
    6274             :                           " seconds in the future\n"),
    6275           0 :                         uid->created - timestamp);
    6276             : 
    6277           0 :               timestamp = uid->created + 1;
    6278             :             }
    6279             : 
    6280           1 :           memset (&attrib, 0, sizeof attrib);
    6281             :           /* should not need to cast away const here; but
    6282             :              revocation_reason_build_cb needs to take a non-const
    6283             :              void* in order to meet the function signtuare for the
    6284             :              mksubpkt argument to make_keysig_packet */
    6285           1 :           attrib.reason = (struct revocation_reason_info *)reason;
    6286             : 
    6287           1 :           rc = make_keysig_packet (&sig, pk, uid, NULL, pk, 0x30, 0,
    6288             :                                    timestamp, 0,
    6289             :                                    sign_mk_attrib, &attrib, NULL);
    6290           1 :           if (rc)
    6291             :             {
    6292           0 :               write_status_error ("keysig", rc);
    6293           0 :               log_error (_("signing failed: %s\n"), gpg_strerror (rc));
    6294           0 :               return 1;
    6295             :             }
    6296             :           else
    6297             :             {
    6298           1 :               pkt = xmalloc_clear (sizeof *pkt);
    6299           1 :               pkt->pkttype = PKT_SIGNATURE;
    6300           1 :               pkt->pkt.signature = sig;
    6301           1 :               insert_kbnode (node, new_kbnode (pkt), 0);
    6302             : 
    6303             : #ifndef NO_TRUST_MODELS
    6304             :               /* If the trustdb has an entry for this key+uid then the
    6305             :                  trustdb needs an update. */
    6306           1 :               if (!update_trust
    6307           2 :                   && ((get_validity (ctrl, keyblock, pk, uid, NULL, 0)
    6308           1 :                        & TRUST_MASK)
    6309             :                       >= TRUST_UNDEFINED))
    6310           1 :                 update_trust = 1;
    6311             : #endif /*!NO_TRUST_MODELS*/
    6312             : 
    6313           1 :               node->pkt->pkt.user_id->is_revoked = 1;
    6314           1 :               if (modified)
    6315           1 :                 *modified = 1;
    6316             :             }
    6317             :         }
    6318           1 :       return 0;
    6319             :     }
    6320             : }
    6321             : 
    6322             : /* Revoke a user ID (i.e. revoke a user ID selfsig).  Return true if
    6323             :    keyblock changed.  */
    6324             : static int
    6325           0 : menu_revuid (ctrl_t ctrl, kbnode_t pub_keyblock)
    6326             : {
    6327           0 :   PKT_public_key *pk = pub_keyblock->pkt->pkt.public_key;
    6328             :   KBNODE node;
    6329           0 :   int changed = 0;
    6330             :   int rc;
    6331           0 :   struct revocation_reason_info *reason = NULL;
    6332             : 
    6333             :   /* Note that this is correct as per the RFCs, but nevertheless
    6334             :      somewhat meaningless in the real world.  1991 did define the 0x30
    6335             :      sig class, but PGP 2.x did not actually implement it, so it would
    6336             :      probably be safe to use v4 revocations everywhere. -ds */
    6337             : 
    6338           0 :   for (node = pub_keyblock; node; node = node->next)
    6339           0 :     if (pk->version > 3 || (node->pkt->pkttype == PKT_USER_ID &&
    6340           0 :                             node->pkt->pkt.user_id->selfsigversion > 3))
    6341             :       {
    6342           0 :         if ((reason = ask_revocation_reason (0, 1, 4)))
    6343           0 :           break;
    6344             :         else
    6345           0 :           goto leave;
    6346             :       }
    6347             : 
    6348             :  reloop: /* (better this way because we are modifying the keyring) */
    6349           0 :   for (node = pub_keyblock; node; node = node->next)
    6350           0 :     if (node->pkt->pkttype == PKT_USER_ID && (node->flag & NODFLG_SELUID))
    6351             :       {
    6352           0 :         int modified = 0;
    6353           0 :         rc = core_revuid (ctrl, pub_keyblock, node, reason, &modified);
    6354           0 :         if (rc)
    6355           0 :           goto leave;
    6356           0 :         if (modified)
    6357             :           {
    6358           0 :             node->flag &= ~NODFLG_SELUID;
    6359           0 :             changed = 1;
    6360           0 :             goto reloop;
    6361             :           }
    6362             :       }
    6363             : 
    6364           0 :   if (changed)
    6365           0 :     commit_kbnode (&pub_keyblock);
    6366             : 
    6367             : leave:
    6368           0 :   release_revocation_reason_info (reason);
    6369           0 :   return changed;
    6370             : }
    6371             : 
    6372             : 
    6373             : /*
    6374             :  * Revoke the whole key.
    6375             :  */
    6376             : static int
    6377           0 : menu_revkey (KBNODE pub_keyblock)
    6378             : {
    6379           0 :   PKT_public_key *pk = pub_keyblock->pkt->pkt.public_key;
    6380           0 :   int rc, changed = 0;
    6381             :   struct revocation_reason_info *reason;
    6382             :   PACKET *pkt;
    6383             :   PKT_signature *sig;
    6384             : 
    6385           0 :   if (pk->flags.revoked)
    6386             :     {
    6387           0 :       tty_printf (_("Key %s is already revoked.\n"), keystr_from_pk (pk));
    6388           0 :       return 0;
    6389             :     }
    6390             : 
    6391           0 :   reason = ask_revocation_reason (1, 0, 0);
    6392             :   /* user decided to cancel */
    6393           0 :   if (!reason)
    6394           0 :     return 0;
    6395             : 
    6396           0 :   rc = make_keysig_packet (&sig, pk, NULL, NULL, pk,
    6397             :                            0x20, 0, 0, 0,
    6398             :                            revocation_reason_build_cb, reason, NULL);
    6399           0 :   if (rc)
    6400             :     {
    6401           0 :       write_status_error ("keysig", rc);
    6402           0 :       log_error (_("signing failed: %s\n"), gpg_strerror (rc));
    6403           0 :       goto scram;
    6404             :     }
    6405             : 
    6406           0 :   changed = 1;                  /* we changed the keyblock */
    6407             : 
    6408           0 :   pkt = xmalloc_clear (sizeof *pkt);
    6409           0 :   pkt->pkttype = PKT_SIGNATURE;
    6410           0 :   pkt->pkt.signature = sig;
    6411           0 :   insert_kbnode (pub_keyblock, new_kbnode (pkt), 0);
    6412           0 :   commit_kbnode (&pub_keyblock);
    6413             : 
    6414           0 :   update_trust = 1;
    6415             : 
    6416             :  scram:
    6417           0 :   release_revocation_reason_info (reason);
    6418           0 :   return changed;
    6419             : }
    6420             : 
    6421             : 
    6422             : static int
    6423           0 : menu_revsubkey (KBNODE pub_keyblock)
    6424             : {
    6425             :   PKT_public_key *mainpk;
    6426             :   KBNODE node;
    6427           0 :   int changed = 0;
    6428             :   int rc;
    6429           0 :   struct revocation_reason_info *reason = NULL;
    6430             : 
    6431           0 :   reason = ask_revocation_reason (1, 0, 0);
    6432           0 :   if (!reason)
    6433           0 :       return 0; /* User decided to cancel.  */
    6434             : 
    6435             :  reloop: /* (better this way because we are modifing the keyring) */
    6436           0 :   mainpk = pub_keyblock->pkt->pkt.public_key;
    6437           0 :   for (node = pub_keyblock; node; node = node->next)
    6438             :     {
    6439           0 :       if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY
    6440           0 :           && (node->flag & NODFLG_SELKEY))
    6441             :         {
    6442             :           PACKET *pkt;
    6443             :           PKT_signature *sig;
    6444           0 :           PKT_public_key *subpk = node->pkt->pkt.public_key;
    6445             :           struct sign_attrib attrib;
    6446             : 
    6447           0 :           if (subpk->flags.revoked)
    6448             :             {
    6449           0 :               tty_printf (_("Subkey %s is already revoked.\n"),
    6450             :                           keystr_from_pk (subpk));
    6451           0 :               continue;
    6452             :             }
    6453             : 
    6454           0 :           memset (&attrib, 0, sizeof attrib);
    6455           0 :           attrib.reason = reason;
    6456             : 
    6457           0 :           node->flag &= ~NODFLG_SELKEY;
    6458           0 :           rc = make_keysig_packet (&sig, mainpk, NULL, subpk, mainpk,
    6459             :                                    0x28, 0, 0, 0, sign_mk_attrib, &attrib,
    6460             :                                    NULL);
    6461           0 :           if (rc)
    6462             :             {
    6463           0 :               write_status_error ("keysig", rc);
    6464           0 :               log_error (_("signing failed: %s\n"), gpg_strerror (rc));
    6465           0 :               release_revocation_reason_info (reason);
    6466           0 :               return changed;
    6467             :             }
    6468           0 :           changed = 1;          /* we changed the keyblock */
    6469             : 
    6470           0 :           pkt = xmalloc_clear (sizeof *pkt);
    6471           0 :           pkt->pkttype = PKT_SIGNATURE;
    6472           0 :           pkt->pkt.signature = sig;
    6473           0 :           insert_kbnode (node, new_kbnode (pkt), 0);
    6474           0 :           goto reloop;
    6475             :         }
    6476             :     }
    6477           0 :   commit_kbnode (&pub_keyblock);
    6478             : 
    6479             :   /* No need to set update_trust here since signing keys no longer
    6480             :      are used to certify other keys, so there is no change in trust
    6481             :      when revoking/removing them */
    6482             : 
    6483           0 :   release_revocation_reason_info (reason);
    6484           0 :   return changed;
    6485             : }
    6486             : 
    6487             : 
    6488             : /* Note that update_ownertrust is going to mark the trustdb dirty when
    6489             :    enabling or disabling a key.  This is arguably sub-optimal as
    6490             :    disabled keys are still counted in the web of trust, but perhaps
    6491             :    not worth adding extra complexity to change. -ds */
    6492             : #ifndef NO_TRUST_MODELS
    6493             : static int
    6494           0 : enable_disable_key (KBNODE keyblock, int disable)
    6495             : {
    6496           0 :   PKT_public_key *pk =
    6497           0 :     find_kbnode (keyblock, PKT_PUBLIC_KEY)->pkt->pkt.public_key;
    6498             :   unsigned int trust, newtrust;
    6499             : 
    6500           0 :   trust = newtrust = get_ownertrust (pk);
    6501           0 :   newtrust &= ~TRUST_FLAG_DISABLED;
    6502           0 :   if (disable)
    6503           0 :     newtrust |= TRUST_FLAG_DISABLED;
    6504           0 :   if (trust == newtrust)
    6505           0 :     return 0;                   /* already in that state */
    6506           0 :   update_ownertrust (pk, newtrust);
    6507           0 :   return 0;
    6508             : }
    6509             : #endif /*!NO_TRUST_MODELS*/
    6510             : 
    6511             : 
    6512             : static void
    6513           0 : menu_showphoto (ctrl_t ctrl, kbnode_t keyblock)
    6514             : {
    6515             :   KBNODE node;
    6516           0 :   int select_all = !count_selected_uids (keyblock);
    6517           0 :   int count = 0;
    6518           0 :   PKT_public_key *pk = NULL;
    6519             : 
    6520             :   /* Look for the public key first.  We have to be really, really,
    6521             :      explicit as to which photo this is, and what key it is a UID on
    6522             :      since people may want to sign it. */
    6523             : 
    6524           0 :   for (node = keyblock; node; node = node->next)
    6525             :     {
    6526           0 :       if (node->pkt->pkttype == PKT_PUBLIC_KEY)
    6527           0 :         pk = node->pkt->pkt.public_key;
    6528           0 :       else if (node->pkt->pkttype == PKT_USER_ID)
    6529             :         {
    6530           0 :           PKT_user_id *uid = node->pkt->pkt.user_id;
    6531           0 :           count++;
    6532             : 
    6533           0 :           if ((select_all || (node->flag & NODFLG_SELUID)) &&
    6534           0 :               uid->attribs != NULL)
    6535             :             {
    6536             :               int i;
    6537             : 
    6538           0 :               for (i = 0; i < uid->numattribs; i++)
    6539             :                 {
    6540             :                   byte type;
    6541             :                   u32 size;
    6542             : 
    6543           0 :                   if (uid->attribs[i].type == ATTRIB_IMAGE &&
    6544           0 :                       parse_image_header (&uid->attribs[i], &type, &size))
    6545             :                     {
    6546           0 :                       tty_printf (_("Displaying %s photo ID of size %ld for "
    6547             :                                     "key %s (uid %d)\n"),
    6548             :                                   image_type_to_string (type, 1),
    6549             :                                   (ulong) size, keystr_from_pk (pk), count);
    6550           0 :                       show_photos (ctrl, &uid->attribs[i], 1, pk, uid);
    6551             :                     }
    6552             :                 }
    6553             :             }
    6554             :         }
    6555             :     }
    6556           0 : }

Generated by: LCOV version 1.11