Coverage Report

Created: 2026-07-30 06:13

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/gnupg/g10/key-check.c
Line
Count
Source
1
/* key-check.c - Detect and fix various problems with keys
2
 * Copyright (C) 1998-2010 Free Software Foundation, Inc.
3
 * Copyright (C) 1998-2017 Werner Koch
4
 * Copyright (C) 2015-2018 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
24
#include "gpg.h"
25
#include "options.h"
26
#include "packet.h"
27
#include "keydb.h"
28
#include "main.h"
29
#include "../common/ttyio.h"
30
#include "../common/i18n.h"
31
#include "keyedit.h"
32
33
#include "key-check.h"
34
35
36
/* Print PREFIX followed by TEXT.  With mode > 0 use log_info, with
37
 * mode < 0 use ttyio, else print to stdout.  If TEXT is not NULL, it
38
 * may be modified by this function.  */
39
static void
40
print_info (int mode, const char *prefix, char *text)
41
8.71k
{
42
8.71k
  char *p;
43
44
8.71k
  if (!text)
45
0
    text = "";
46
8.71k
  else if ((p = strchr (text,'\n')))
47
8.71k
    *p = 0; /* Strip LF.  */
48
49
8.71k
   if (mode > 0)
50
8.71k
     log_info ("%s %s\n", prefix, text);
51
0
   else
52
0
     tty_fprintf (mode? NULL:es_stdout, "%s %s\n", prefix, text);
53
8.71k
}
54
55
56
/* Order two signatures.  The actual ordering isn't important.  Our
57
 * goal is to ensure that identical signatures occur together.  */
58
static int
59
sig_comparison (const void *av, const void *bv)
60
89.4k
{
61
89.4k
  const KBNODE an = *(const KBNODE *) av;
62
89.4k
  const KBNODE bn = *(const KBNODE *) bv;
63
89.4k
  const PKT_signature *a;
64
89.4k
  const PKT_signature *b;
65
89.4k
  int ndataa;
66
89.4k
  int ndatab;
67
89.4k
  int i;
68
69
89.4k
  log_assert (an->pkt->pkttype == PKT_SIGNATURE);
70
89.4k
  log_assert (bn->pkt->pkttype == PKT_SIGNATURE);
71
72
89.4k
  a = an->pkt->pkt.signature;
73
89.4k
  b = bn->pkt->pkt.signature;
74
75
  /* Signatures with a different help counter are not identical for
76
   * our purpose.  */
77
89.4k
  if (a->help_counter < b->help_counter)
78
65.9k
    return -1;
79
23.4k
  if (a->help_counter > b->help_counter)
80
0
    return 1;
81
82
23.4k
  if (a->digest_algo < b->digest_algo)
83
6.67k
    return -1;
84
16.8k
  if (a->digest_algo > b->digest_algo)
85
1.76k
    return 1;
86
87
15.0k
  ndataa = pubkey_get_nsig (a->pubkey_algo);
88
15.0k
  ndatab = pubkey_get_nsig (b->pubkey_algo);
89
15.0k
  if (ndataa != ndatab)
90
312
    return (ndataa < ndatab)? -1 : 1;
91
92
17.7k
  for (i = 0; i < ndataa; i ++)
93
7.12k
    {
94
7.12k
      int c = gcry_mpi_cmp (a->data[i], b->data[i]);
95
7.12k
      if (c != 0)
96
4.10k
        return c;
97
7.12k
    }
98
99
  /* Okay, they are equal.  */
100
10.6k
  return 0;
101
14.7k
}
102
103
104
static gpg_error_t
105
remove_duplicate_sigs (kbnode_t kb, int *dups, int *modified)
106
11.4k
{
107
11.4k
  gpg_error_t err;
108
11.4k
  kbnode_t n;
109
11.4k
  int nsigs;
110
11.4k
  kbnode_t *sigs;  /* Allocated array with the signature packet.  */
111
11.4k
  int i;
112
11.4k
  int last_i;
113
11.4k
  int block;
114
11.4k
  PKT_signature *sig;
115
116
  /* Count the sigs.  */
117
92.4k
  for (nsigs = 0, n = kb; n; n = n->next)
118
80.9k
    {
119
80.9k
      if (is_deleted_kbnode (n))
120
0
        continue;
121
80.9k
      else if (n->pkt->pkttype == PKT_SIGNATURE)
122
32.9k
        nsigs ++;
123
80.9k
    }
124
125
11.4k
  if (!nsigs)
126
1.78k
    return 0; /* No signatures at all.  */
127
128
  /* Add them all to the SIGS array.  */
129
9.66k
  sigs = xtrycalloc (nsigs, sizeof *sigs);
130
9.66k
  if (!sigs)
131
0
    {
132
0
      err = gpg_error_from_syserror ();
133
0
      log_error (_("error allocating memory: %s\n"), gpg_strerror (err));
134
0
      return err;
135
0
    }
136
137
9.66k
  block = 0;
138
9.66k
  i = 0;
139
84.3k
  for (n = kb; n; n = n->next)
140
74.7k
    {
141
74.7k
      if (is_deleted_kbnode (n))
142
0
        continue;
143
144
74.7k
      if (n->pkt->pkttype != PKT_SIGNATURE)
145
41.8k
        {
146
41.8k
          switch (n->pkt->pkttype)
147
41.8k
            {
148
3.70k
            case PKT_PUBLIC_SUBKEY:
149
4.16k
            case PKT_SECRET_SUBKEY:
150
32.1k
            case PKT_USER_ID:
151
32.1k
            case PKT_ATTRIBUTE:
152
              /* Bump the block number so that we only consider
153
               * signatures below the same object as duplicates.  */
154
32.1k
              block++;
155
32.1k
              break;
156
9.66k
            default:
157
9.66k
              break;
158
41.8k
            }
159
41.8k
          continue;
160
41.8k
        }
161
32.9k
      sig = n->pkt->pkt.signature;
162
32.9k
      sig->help_counter = block;
163
32.9k
      sigs[i++] = n;
164
32.9k
    }
165
9.66k
  log_assert (i == nsigs);
166
167
9.66k
  qsort (sigs, nsigs, sizeof (sigs[0]), sig_comparison);
168
169
9.66k
  last_i = 0;
170
32.9k
  for (i = 1; i < nsigs; i ++)
171
23.2k
    {
172
23.2k
      log_assert (sigs[last_i]);
173
23.2k
      log_assert (sigs[last_i]->pkt->pkttype == PKT_SIGNATURE);
174
23.2k
      log_assert (sigs[i]);
175
23.2k
      log_assert (sigs[i]->pkt->pkttype == PKT_SIGNATURE);
176
177
23.2k
      if (sig_comparison (&sigs[last_i], &sigs[i]) == 0)
178
3.30k
        {
179
          /* They are the same.  Kill the latter.  */
180
3.30k
          if (DBG_PACKET)
181
0
            {
182
0
              sig = sigs[i]->pkt->pkt.signature;
183
184
0
              log_debug ("Signature appears multiple times, "
185
0
                         "deleting duplicate:\n");
186
0
              log_debug ("  sig: class 0x%x, issuer: %s,"
187
0
                         " timestamp: %s (%lld), digest: %02x %02x\n",
188
0
                         sig->sig_class, keystr (sig->keyid),
189
0
                         isotimestamp (sig->timestamp),
190
0
                         (long long) sig->timestamp,
191
0
                         sig->digest_start[0], sig->digest_start[1]);
192
0
            }
193
194
          /* Remove sigs[i] from the keyblock.  */
195
3.30k
          {
196
3.30k
            kbnode_t z, *prevp;
197
3.30k
            int to_kill = last_i;
198
3.30k
            last_i = i;
199
200
715k
            for (prevp = &kb, z = kb; z; prevp = &z->next, z = z->next)
201
715k
              if (z == sigs[to_kill])
202
3.30k
                break;
203
204
3.30k
            *prevp = sigs[to_kill]->next;
205
206
3.30k
            sigs[to_kill]->next = NULL;
207
3.30k
            release_kbnode (sigs[to_kill]);
208
3.30k
            sigs[to_kill] = NULL;
209
210
3.30k
            ++*dups;
211
3.30k
            *modified = 1;
212
3.30k
          }
213
3.30k
        }
214
19.9k
      else
215
19.9k
        last_i = i;
216
23.2k
    }
217
218
9.66k
  xfree (sigs);
219
9.66k
  return 0;
220
9.66k
}
221
222
223
/* Perform a few sanity checks on a keyblock is okay and possibly
224
 * repair some damage.  Concretely:
225
 *
226
 *   - Detect duplicate signatures and remove them.
227
 *
228
 *   - Detect out of order signatures and relocate them (e.g., a sig
229
 *     over user id X located under subkey Y).
230
 *
231
 * Note: this function does not remove signatures that don't belong or
232
 * components that are not signed!  (Although it would be trivial to
233
 * do so.)
234
 *
235
 * If ONLY_SELFSIGS is true, then this function only reorders self
236
 * signatures (it still checks all signatures for duplicates,
237
 * however).
238
 *
239
 * Allowed values for MODE are:
240
 *  -1 - print to the TTY
241
 *   0 - print to stdout
242
 *   1 - use log_info.
243
 *
244
 * Returns true if the keyblock was modified.  */
245
int
246
key_check_all_keysigs (ctrl_t ctrl, int mode, kbnode_t kb,
247
                       int only_selected, int only_selfsigs)
248
10.9k
{
249
10.9k
  gpg_error_t err;
250
10.9k
  PKT_public_key *pk;
251
10.9k
  KBNODE n, n_next, *n_prevp, n2;
252
10.9k
  char *pending_desc = NULL;
253
10.9k
  PKT_public_key *issuer;
254
10.9k
  KBNODE last_printed_component;
255
10.9k
  KBNODE current_component = NULL;
256
10.9k
  int dups = 0;
257
10.9k
  int missing_issuer = 0;
258
10.9k
  int reordered = 0;
259
10.9k
  int bad_signature = 0;
260
10.9k
  int missing_selfsig = 0;
261
10.9k
  int modified = 0;
262
10.9k
  PKT_signature *sig;
263
264
10.9k
  (void)missing_selfsig;
265
10.9k
  log_assert (kb->pkt->pkttype == PKT_PUBLIC_KEY);
266
10.9k
  pk = kb->pkt->pkt.public_key;
267
268
  /* First we look for duplicates.  */
269
10.9k
  if (remove_duplicate_sigs (kb, &dups, &modified))
270
0
    goto leave;  /* Error */
271
272
  /* Now make sure the sigs occur after the component (aka block)
273
   * (public key, subkey, user id) that they sign.  */
274
10.9k
  issuer = NULL;
275
10.9k
  last_printed_component = NULL;
276
10.9k
  for (n_prevp = &kb, n = kb;
277
83.3k
       n;
278
       /* If we moved n, then n_prevp is need valid.  */
279
72.4k
       n_prevp = (n->next == n_next ? &n->next : n_prevp), n = n_next)
280
72.4k
    {
281
72.4k
      PACKET *p;
282
72.4k
      int processed_current_component;
283
72.4k
      int rc;
284
72.4k
      int dump_sig_params = 0;
285
286
72.4k
      n_next = n->next;
287
288
72.4k
      if (is_deleted_kbnode (n))
289
0
        continue;
290
291
72.4k
      p = n->pkt;
292
293
72.4k
      if (issuer && issuer != pk)
294
2.52k
        {
295
2.52k
          free_public_key (issuer);
296
2.52k
          issuer = NULL;
297
2.52k
        }
298
299
72.4k
      xfree (pending_desc);
300
72.4k
      pending_desc = NULL;
301
302
72.4k
      switch (p->pkttype)
303
72.4k
        {
304
10.9k
        case PKT_PUBLIC_KEY:
305
10.9k
          log_assert (p->pkt.public_key == pk);
306
10.9k
          if (only_selected && ! (n->flag & NODFLG_SELKEY))
307
0
            {
308
0
              current_component = NULL;
309
0
              break;
310
0
            }
311
312
10.9k
          if (DBG_PACKET)
313
10.9k
            log_debug ("public key %s: timestamp: %s (%lld)\n",
314
0
                       pk_keyid_str (pk),
315
0
                       isotimestamp (pk->timestamp),
316
0
                       (long long) pk->timestamp);
317
10.9k
          current_component = n;
318
10.9k
          break;
319
3.73k
        case PKT_PUBLIC_SUBKEY:
320
3.73k
          if (only_selected && ! (n->flag & NODFLG_SELKEY))
321
0
            {
322
0
              current_component = NULL;
323
0
              break;
324
0
            }
325
326
3.73k
          if (DBG_PACKET)
327
3.73k
            log_debug ("subkey %s: timestamp: %s (%lld)\n",
328
0
                       pk_keyid_str (p->pkt.public_key),
329
0
                       isotimestamp (p->pkt.public_key->timestamp),
330
0
                       (long long) p->pkt.public_key->timestamp);
331
3.73k
          current_component = n;
332
3.73k
          break;
333
29.9k
        case PKT_USER_ID:
334
29.9k
          if (only_selected && ! (n->flag & NODFLG_SELUID))
335
0
            {
336
0
              current_component = NULL;
337
0
              break;
338
0
            }
339
340
29.9k
          if (DBG_PACKET)
341
29.9k
            log_debug ("user id: %s\n",
342
0
                       p->pkt.user_id->attrib_data
343
0
                       ? "[ photo id ]"
344
0
                       : p->pkt.user_id->name);
345
29.9k
          current_component = n;
346
29.9k
          break;
347
27.1k
        case PKT_SIGNATURE:
348
27.1k
          if (! current_component)
349
            /* The current component is not selected, don't check the
350
               sigs under it.  */
351
0
            break;
352
353
27.1k
          sig = n->pkt->pkt.signature;
354
355
27.1k
          pending_desc = xasprintf ("  sig: class: 0x%x, issuer: %s,"
356
27.1k
                                    " timestamp: %s (%lld), digest: %02x %02x",
357
27.1k
                                    sig->sig_class,
358
27.1k
                                    keystr (sig->keyid),
359
27.1k
                                    isotimestamp (sig->timestamp),
360
27.1k
                                    (long long) sig->timestamp,
361
27.1k
                                    sig->digest_start[0], sig->digest_start[1]);
362
363
364
27.1k
          if (keyid_cmp (pk_keyid (pk), sig->keyid) == 0)
365
9.73k
            issuer = pk;
366
17.4k
          else /* Issuer is a different key.  */
367
17.4k
            {
368
17.4k
              if (only_selfsigs)
369
0
                continue;
370
371
17.4k
              issuer = xtrycalloc (1, sizeof *issuer);
372
17.4k
              if (!issuer)
373
0
                err = gpg_error_from_syserror ();
374
17.4k
              else
375
17.4k
                err = get_pubkey (ctrl, issuer, sig->keyid);
376
17.4k
              if (err)
377
14.6k
                {
378
14.6k
                  xfree (issuer);
379
14.6k
                  issuer = NULL;
380
14.6k
                  if (DBG_PACKET)
381
0
                    {
382
0
                      if (pending_desc)
383
0
                        log_debug ("%s", pending_desc);
384
0
                      log_debug ("    Can't check signature allegedly"
385
0
                                 " issued by %s: %s\n",
386
0
                                 keystr (sig->keyid), gpg_strerror (err));
387
0
                    }
388
14.6k
                  missing_issuer ++;
389
14.6k
                  break;
390
14.6k
                }
391
17.4k
            }
392
393
12.5k
          if ((err = openpgp_pk_test_algo (sig->pubkey_algo)))
394
557
            {
395
557
              if (DBG_PACKET && pending_desc)
396
557
                log_debug ("%s", pending_desc);
397
557
              log_info (_("can't check signature with unsupported"
398
557
                          " public-key algorithm (%d): %s.\n"),
399
557
                          sig->pubkey_algo, gpg_strerror (err));
400
557
              break;
401
557
            }
402
11.9k
          if ((err = openpgp_md_test_algo (sig->digest_algo)))
403
1.49k
            {
404
1.49k
              if (DBG_PACKET && pending_desc)
405
1.49k
                log_debug ("%s", pending_desc);
406
1.49k
              log_info (_("can't check signature with unsupported"
407
1.49k
                          " message-digest algorithm %d: %s.\n"),
408
1.49k
                          sig->digest_algo, gpg_strerror (err));
409
1.49k
              break;
410
1.49k
            }
411
412
          /* We iterate over the keyblock.  Most likely, the matching
413
             component is the current component so always try that
414
             first.  */
415
10.4k
          processed_current_component = 0;
416
10.4k
          for (n2 = current_component;
417
666k
               n2;
418
656k
               n2 = (processed_current_component ? n2->next : kb),
419
656k
                 processed_current_component = 1)
420
660k
            if (is_deleted_kbnode (n2))
421
0
              continue;
422
660k
            else if (processed_current_component && n2 == current_component)
423
              /* Don't process it twice.  */
424
6.59k
              continue;
425
653k
            else
426
653k
              {
427
653k
                err = check_signature_over_key_or_uid (ctrl,
428
653k
                                                       issuer, sig, kb, n2->pkt,
429
653k
                                                       NULL, NULL);
430
653k
                if (! err)
431
4.00k
                  break;
432
653k
              }
433
434
          /* n/sig is a signature and n2 is the component (public key,
435
             subkey or user id) that it signs, if any.
436
             current_component is that component that it appears to
437
             apply to (according to the ordering).  */
438
439
10.4k
          if (current_component == n2)
440
3.20k
            {
441
3.20k
              if (DBG_PACKET)
442
0
                {
443
0
                  log_debug ("%s", pending_desc);
444
0
                  log_debug ("    Good signature over last key or uid!\n");
445
0
                }
446
447
3.20k
              rc = 0;
448
3.20k
            }
449
7.25k
          else if (n2)
450
799
            {
451
799
              log_assert (n2->pkt->pkttype == PKT_USER_ID
452
799
                          || n2->pkt->pkttype == PKT_PUBLIC_KEY
453
799
                          || n2->pkt->pkttype == PKT_PUBLIC_SUBKEY);
454
455
799
              if (DBG_PACKET)
456
0
                {
457
0
                  log_debug ("%s", pending_desc);
458
0
                  log_debug ("    Good signature out of order!"
459
0
                             "  (Over %s (%d) '%s')\n",
460
0
                             n2->pkt->pkttype == PKT_USER_ID
461
0
                             ? "user id"
462
0
                             : n2->pkt->pkttype == PKT_PUBLIC_SUBKEY
463
0
                             ? "subkey"
464
0
                             : "primary key",
465
0
                             n2->pkt->pkttype,
466
0
                             n2->pkt->pkttype == PKT_USER_ID
467
0
                             ? n2->pkt->pkt.user_id->name
468
0
                             : pk_keyid_str (n2->pkt->pkt.public_key));
469
0
                }
470
471
              /* Reorder the packets: move the signature n to be just
472
                 after n2.  */
473
474
              /* Unlink the signature.  */
475
799
              log_assert (n_prevp);
476
799
              *n_prevp = n->next;
477
478
              /* Insert the sig immediately after the component.  */
479
799
              n->next = n2->next;
480
799
              n2->next = n;
481
482
799
              reordered ++;
483
799
              modified = 1;
484
485
799
              rc = 0;
486
799
            }
487
6.45k
          else
488
6.45k
            {
489
6.45k
              if (DBG_PACKET)
490
0
                {
491
0
                  log_debug ("%s", pending_desc);
492
0
                  log_debug ("    Bad signature.\n");
493
0
                }
494
495
6.45k
              if (DBG_PACKET)
496
0
                dump_sig_params = 1;
497
498
6.45k
              bad_signature ++;
499
500
6.45k
              rc = GPG_ERR_BAD_SIGNATURE;
501
6.45k
            }
502
503
          /* We don't cache the result here, because we haven't
504
             completely checked that the signature is legitimate.  For
505
             instance, if we have a revocation certificate on Alice's
506
             key signed by Bob, the signature may be good, but we
507
             haven't checked that Bob is a designated revoker.  */
508
          /* cache_sig_result (sig, rc); */
509
510
10.4k
          {
511
10.4k
            int has_selfsig = 0;
512
10.4k
            if (! rc && issuer == pk)
513
3.95k
              {
514
3.95k
                if (n2->pkt->pkttype == PKT_PUBLIC_KEY
515
179
                    && (/* Direct key signature.  */
516
179
                        sig->sig_class == 0x1f
517
                        /* Key revocation signature.  */
518
161
                        || sig->sig_class == 0x20))
519
179
                  has_selfsig = 1;
520
3.95k
                if (n2->pkt->pkttype == PKT_PUBLIC_SUBKEY
521
689
                    && (/* Subkey binding sig.  */
522
689
                        sig->sig_class == 0x18
523
                        /* Subkey revocation sig.  */
524
58
                        || sig->sig_class == 0x28))
525
689
                  has_selfsig = 1;
526
3.95k
                if (n2->pkt->pkttype == PKT_USER_ID
527
3.08k
                    && (/* Certification sigs.  */
528
3.08k
                        sig->sig_class == 0x10
529
3.00k
                        || sig->sig_class == 0x11
530
3.00k
                        || sig->sig_class == 0x12
531
3.00k
                        || sig->sig_class == 0x13
532
                        /* Certification revocation sig.  */
533
296
                        || sig->sig_class == 0x30))
534
3.08k
                  has_selfsig = 1;
535
3.95k
              }
536
537
10.4k
            if (DBG_PACKET
538
0
                && ((n2 && n2 != last_printed_component)
539
0
                    || (! n2 && last_printed_component != current_component)))
540
0
              {
541
0
                int is_reordered = n2 && n2 != current_component;
542
0
                if (n2)
543
0
                  last_printed_component = n2;
544
0
                else
545
0
                  last_printed_component = current_component;
546
547
0
                if (!modified)
548
0
                  ;
549
0
                else if (last_printed_component->pkt->pkttype == PKT_USER_ID)
550
0
                  {
551
0
                    log_debug ("uid  ");
552
0
                    print_utf8_buffer (log_get_stream (),
553
0
                                       last_printed_component
554
0
                                       ->pkt->pkt.user_id->name,
555
0
                                       last_printed_component
556
0
                                       ->pkt->pkt.user_id->len);
557
0
                    log_flush ();
558
0
                  }
559
0
                else if (last_printed_component->pkt->pkttype
560
0
                         == PKT_PUBLIC_KEY)
561
0
                  log_debug ("pub  %s\n",
562
0
                             pk_keyid_str (last_printed_component
563
0
                                             ->pkt->pkt.public_key));
564
0
                else
565
0
                  log_debug ("sub  %s\n",
566
0
                             pk_keyid_str (last_printed_component
567
0
                                           ->pkt->pkt.public_key));
568
569
0
                if (modified)
570
0
                  {
571
0
                    if (is_reordered)
572
0
                      log_debug ("%s\n", _(" (reordered signatures follow)"));
573
0
                  }
574
0
              }
575
576
10.4k
            if (DBG_PACKET && modified)
577
0
              keyedit_print_one_sig (ctrl, log_get_stream (),
578
0
                                     rc, kb, n, NULL, NULL, NULL,
579
0
             has_selfsig, 0, only_selfsigs);
580
10.4k
          }
581
582
10.4k
          if (dump_sig_params)
583
0
            {
584
0
              int i;
585
586
0
              for (i = 0; i < pubkey_get_nsig (sig->pubkey_algo); i ++)
587
0
                {
588
0
                  char buffer[1024];
589
0
                  size_t len;
590
0
                  char *printable;
591
0
                  if (gcry_mpi_get_flag (sig->data[i], GCRYMPI_FLAG_OPAQUE))
592
0
                    {
593
0
                      const byte *sigdata;
594
0
                      unsigned int nbits;
595
596
0
                      sigdata = gcry_mpi_get_opaque (sig->data[i], &nbits);
597
0
                      len = (nbits+7)/8;
598
0
                      memcpy (buffer, sigdata, len);
599
0
                    }
600
0
                  else
601
0
                    gcry_mpi_print (GCRYMPI_FMT_USG,
602
0
                                    buffer, sizeof (buffer), &len,
603
0
                                    sig->data[i]);
604
0
                  printable = bin2hex (buffer, len, NULL);
605
0
                  log_debug ("        %d: %s\n", i, printable);
606
0
                  xfree (printable);
607
0
                }
608
0
            }
609
10.4k
          break;
610
736
        default:
611
736
          if (DBG_PACKET)
612
736
            log_debug ("unhandled packet: %d\n", p->pkttype);
613
736
          break;
614
72.4k
        }
615
72.4k
    }
616
617
10.9k
  xfree (pending_desc);
618
10.9k
  pending_desc = NULL;
619
620
10.9k
  if (issuer != pk)
621
7.08k
    free_public_key (issuer);
622
10.9k
  issuer = NULL;
623
624
  /* If we reordered signatures we need to de-duplicate again because
625
   * a signature can now be a duplicate in another block.  */
626
10.9k
  if (reordered)
627
538
    {
628
538
      if (remove_duplicate_sigs (kb, &dups, &modified))
629
0
        goto leave;
630
538
    }
631
632
  /* Identify keys / uids that don't have a self-sig.  */
633
10.9k
  {
634
10.9k
    int has_selfsig = 0;
635
10.9k
    PACKET *p;
636
637
10.9k
    current_component = NULL;
638
83.0k
    for (n = kb; n; n = n->next)
639
72.1k
      {
640
72.1k
        if (is_deleted_kbnode (n))
641
0
          continue;
642
643
72.1k
        p = n->pkt;
644
645
72.1k
        switch (p->pkttype)
646
72.1k
          {
647
10.9k
          case PKT_PUBLIC_KEY:
648
14.6k
          case PKT_PUBLIC_SUBKEY:
649
44.5k
          case PKT_USER_ID:
650
44.5k
            if (current_component && ! has_selfsig)
651
33.2k
              missing_selfsig ++;
652
44.5k
            current_component = n;
653
44.5k
            has_selfsig = 0;
654
44.5k
            break;
655
656
26.7k
          case PKT_SIGNATURE:
657
26.7k
            if (! current_component || has_selfsig)
658
158
              break;
659
660
26.6k
            sig = n->pkt->pkt.signature;
661
662
26.6k
            if (! (sig->flags.checked && sig->flags.valid))
663
26.6k
              break;
664
665
0
            if (keyid_cmp (pk_keyid (pk), sig->keyid) != 0)
666
              /* Different issuer, couldn't be a self-sig.  */
667
0
              break;
668
669
0
            if (current_component->pkt->pkttype == PKT_PUBLIC_KEY
670
0
                && (/* Direct key signature.  */
671
0
                    sig->sig_class == 0x1f
672
                    /* Key revocation signature.  */
673
0
                    || sig->sig_class == 0x20))
674
0
              has_selfsig = 1;
675
0
            if (current_component->pkt->pkttype == PKT_PUBLIC_SUBKEY
676
0
                && (/* Subkey binding sig.  */
677
0
                    sig->sig_class == 0x18
678
                    /* Subkey revocation sig.  */
679
0
                    || sig->sig_class == 0x28))
680
0
              has_selfsig = 1;
681
0
            if (current_component->pkt->pkttype == PKT_USER_ID
682
0
                && (/* Certification sigs.  */
683
0
                    sig->sig_class == 0x10
684
0
                    || sig->sig_class == 0x11
685
0
                    || sig->sig_class == 0x12
686
0
                    || sig->sig_class == 0x13
687
                    /* Certification revocation sig.  */
688
0
                    || sig->sig_class == 0x30))
689
0
              has_selfsig = 1;
690
691
0
            break;
692
693
736
          default:
694
736
            if (current_component && ! has_selfsig)
695
529
              missing_selfsig ++;
696
736
            current_component = NULL;
697
72.1k
          }
698
72.1k
      }
699
10.9k
  }
700
701
702
10.9k
 leave:
703
10.9k
  if (!opt.quiet)
704
10.9k
    {
705
10.9k
      char prefix[100];
706
10.9k
      char *p;
707
708
      /* To avoid string changes in 2.2 we strip the LF here. */
709
10.9k
      snprintf (prefix, sizeof prefix, _("key %s:\n"), pk_keyid_str (pk));
710
10.9k
      p = strrchr (prefix, '\n');
711
10.9k
      if (p)
712
10.9k
        *p = 0;
713
714
10.9k
      if (dups)
715
823
        {
716
823
          p = xtryasprintf
717
823
            (ngettext ("%d duplicate signature removed\n",
718
823
                       "%d duplicate signatures removed\n", dups), dups);
719
823
          print_info (mode, prefix, p);
720
823
          xfree (p);
721
823
        }
722
723
10.9k
      if (missing_issuer)
724
4.65k
        {
725
4.65k
          p = xtryasprintf
726
4.65k
            (ngettext ("%d signature not checked due to a missing key\n",
727
4.65k
                       "%d signatures not checked due to missing keys\n",
728
4.65k
                       missing_issuer), missing_issuer);
729
4.65k
          print_info (mode, prefix, p);
730
4.65k
          xfree (p);
731
4.65k
        }
732
10.9k
      if (bad_signature)
733
2.69k
        {
734
2.69k
          p = xtryasprintf (ngettext ("%d bad signature\n",
735
2.69k
                                      "%d bad signatures\n",
736
2.69k
                                      bad_signature), bad_signature);
737
2.69k
          print_info (mode, prefix, p);
738
2.69k
          xfree (p);
739
2.69k
        }
740
741
10.9k
      if (reordered)
742
538
        {
743
538
          p = xtryasprintf (ngettext ("%d signature reordered\n",
744
538
                                      "%d signatures reordered\n",
745
538
                                      reordered), reordered);
746
538
          print_info (mode, prefix, p);
747
538
          xfree (p);
748
538
        }
749
750
10.9k
      if (only_selfsigs && (bad_signature || reordered))
751
0
        {
752
0
          p = xtryasprintf
753
0
            (_("Warning: errors found and only checked self-signatures,"
754
0
               " run '%s' to check all signatures.\n"), "check");
755
0
          print_info (mode, prefix, p);
756
0
          xfree (p);
757
0
        }
758
10.9k
    }
759
760
10.9k
  return modified;
761
10.9k
}