Coverage Report

Created: 2026-04-12 06:38

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
6.35k
{
42
6.35k
  char *p;
43
44
6.35k
  if (!text)
45
0
    text = "";
46
6.35k
  else if ((p = strchr (text,'\n')))
47
6.35k
    *p = 0; /* Strip LF.  */
48
49
6.35k
   if (mode > 0)
50
6.35k
     log_info ("%s %s\n", prefix, text);
51
0
   else
52
0
     tty_fprintf (mode? NULL:es_stdout, "%s %s\n", prefix, text);
53
6.35k
}
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
56.6k
{
61
56.6k
  const KBNODE an = *(const KBNODE *) av;
62
56.6k
  const KBNODE bn = *(const KBNODE *) bv;
63
56.6k
  const PKT_signature *a;
64
56.6k
  const PKT_signature *b;
65
56.6k
  int ndataa;
66
56.6k
  int ndatab;
67
56.6k
  int i;
68
69
56.6k
  log_assert (an->pkt->pkttype == PKT_SIGNATURE);
70
56.6k
  log_assert (bn->pkt->pkttype == PKT_SIGNATURE);
71
72
56.6k
  a = an->pkt->pkt.signature;
73
56.6k
  b = bn->pkt->pkt.signature;
74
75
  /* Signatures with a different help counter are not identical for
76
   * our purpose.  */
77
56.6k
  if (a->help_counter < b->help_counter)
78
40.3k
    return -1;
79
16.2k
  if (a->help_counter > b->help_counter)
80
0
    return 1;
81
82
16.2k
  if (a->digest_algo < b->digest_algo)
83
5.87k
    return -1;
84
10.3k
  if (a->digest_algo > b->digest_algo)
85
1.52k
    return 1;
86
87
8.86k
  ndataa = pubkey_get_nsig (a->pubkey_algo);
88
8.86k
  ndatab = pubkey_get_nsig (b->pubkey_algo);
89
8.86k
  if (ndataa != ndatab)
90
417
    return (ndataa < ndatab)? -1 : 1;
91
92
10.8k
  for (i = 0; i < ndataa; i ++)
93
5.58k
    {
94
5.58k
      int c = gcry_mpi_cmp (a->data[i], b->data[i]);
95
5.58k
      if (c != 0)
96
3.16k
        return c;
97
5.58k
    }
98
99
  /* Okay, they are equal.  */
100
5.28k
  return 0;
101
8.44k
}
102
103
104
static gpg_error_t
105
remove_duplicate_sigs (kbnode_t kb, int *dups, int *modified)
106
8.59k
{
107
8.59k
  gpg_error_t err;
108
8.59k
  kbnode_t n;
109
8.59k
  int nsigs;
110
8.59k
  kbnode_t *sigs;  /* Allocated array with the signature packet.  */
111
8.59k
  int i;
112
8.59k
  int last_i;
113
8.59k
  int block;
114
8.59k
  PKT_signature *sig;
115
116
  /* Count the sigs.  */
117
67.0k
  for (nsigs = 0, n = kb; n; n = n->next)
118
58.4k
    {
119
58.4k
      if (is_deleted_kbnode (n))
120
0
        continue;
121
58.4k
      else if (n->pkt->pkttype == PKT_SIGNATURE)
122
22.7k
        nsigs ++;
123
58.4k
    }
124
125
8.59k
  if (!nsigs)
126
1.22k
    return 0; /* No signatures at all.  */
127
128
  /* Add them all to the SIGS array.  */
129
7.36k
  sigs = xtrycalloc (nsigs, sizeof *sigs);
130
7.36k
  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
7.36k
  block = 0;
138
7.36k
  i = 0;
139
60.6k
  for (n = kb; n; n = n->next)
140
53.2k
    {
141
53.2k
      if (is_deleted_kbnode (n))
142
0
        continue;
143
144
53.2k
      if (n->pkt->pkttype != PKT_SIGNATURE)
145
30.5k
        {
146
30.5k
          switch (n->pkt->pkttype)
147
30.5k
            {
148
3.11k
            case PKT_PUBLIC_SUBKEY:
149
3.31k
            case PKT_SECRET_SUBKEY:
150
23.1k
            case PKT_USER_ID:
151
23.1k
            case PKT_ATTRIBUTE:
152
              /* Bump the block number so that we only consider
153
               * signatures below the same object as duplicates.  */
154
23.1k
              block++;
155
23.1k
              break;
156
7.36k
            default:
157
7.36k
              break;
158
30.5k
            }
159
30.5k
          continue;
160
30.5k
        }
161
22.7k
      sig = n->pkt->pkt.signature;
162
22.7k
      sig->help_counter = block;
163
22.7k
      sigs[i++] = n;
164
22.7k
    }
165
7.36k
  log_assert (i == nsigs);
166
167
7.36k
  qsort (sigs, nsigs, sizeof (sigs[0]), sig_comparison);
168
169
7.36k
  last_i = 0;
170
22.7k
  for (i = 1; i < nsigs; i ++)
171
15.3k
    {
172
15.3k
      log_assert (sigs[last_i]);
173
15.3k
      log_assert (sigs[last_i]->pkt->pkttype == PKT_SIGNATURE);
174
15.3k
      log_assert (sigs[i]);
175
15.3k
      log_assert (sigs[i]->pkt->pkttype == PKT_SIGNATURE);
176
177
15.3k
      if (sig_comparison (&sigs[last_i], &sigs[i]) == 0)
178
1.61k
        {
179
          /* They are the same.  Kill the latter.  */
180
1.61k
          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
1.61k
          {
196
1.61k
            kbnode_t z, *prevp;
197
1.61k
            int to_kill = last_i;
198
1.61k
            last_i = i;
199
200
410k
            for (prevp = &kb, z = kb; z; prevp = &z->next, z = z->next)
201
410k
              if (z == sigs[to_kill])
202
1.61k
                break;
203
204
1.61k
            *prevp = sigs[to_kill]->next;
205
206
1.61k
            sigs[to_kill]->next = NULL;
207
1.61k
            release_kbnode (sigs[to_kill]);
208
1.61k
            sigs[to_kill] = NULL;
209
210
1.61k
            ++*dups;
211
1.61k
            *modified = 1;
212
1.61k
          }
213
1.61k
        }
214
13.7k
      else
215
13.7k
        last_i = i;
216
15.3k
    }
217
218
7.36k
  xfree (sigs);
219
7.36k
  return 0;
220
7.36k
}
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
8.18k
{
249
8.18k
  gpg_error_t err;
250
8.18k
  PKT_public_key *pk;
251
8.18k
  KBNODE n, n_next, *n_prevp, n2;
252
8.18k
  char *pending_desc = NULL;
253
8.18k
  PKT_public_key *issuer;
254
8.18k
  KBNODE last_printed_component;
255
8.18k
  KBNODE current_component = NULL;
256
8.18k
  int dups = 0;
257
8.18k
  int missing_issuer = 0;
258
8.18k
  int reordered = 0;
259
8.18k
  int bad_signature = 0;
260
8.18k
  int missing_selfsig = 0;
261
8.18k
  int modified = 0;
262
8.18k
  PKT_signature *sig;
263
264
8.18k
  (void)missing_selfsig;
265
8.18k
  log_assert (kb->pkt->pkttype == PKT_PUBLIC_KEY);
266
8.18k
  pk = kb->pkt->pkt.public_key;
267
268
  /* First we look for duplicates.  */
269
8.18k
  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
8.18k
  issuer = NULL;
275
8.18k
  last_printed_component = NULL;
276
8.18k
  for (n_prevp = &kb, n = kb;
277
60.8k
       n;
278
       /* If we moved n, then n_prevp is need valid.  */
279
52.6k
       n_prevp = (n->next == n_next ? &n->next : n_prevp), n = n_next)
280
52.6k
    {
281
52.6k
      PACKET *p;
282
52.6k
      int processed_current_component;
283
52.6k
      int rc;
284
52.6k
      int dump_sig_params = 0;
285
286
52.6k
      n_next = n->next;
287
288
52.6k
      if (is_deleted_kbnode (n))
289
0
        continue;
290
291
52.6k
      p = n->pkt;
292
293
52.6k
      if (issuer && issuer != pk)
294
1.92k
        {
295
1.92k
          free_public_key (issuer);
296
1.92k
          issuer = NULL;
297
1.92k
        }
298
299
52.6k
      xfree (pending_desc);
300
52.6k
      pending_desc = NULL;
301
302
52.6k
      switch (p->pkttype)
303
52.6k
        {
304
8.18k
        case PKT_PUBLIC_KEY:
305
8.18k
          log_assert (p->pkt.public_key == pk);
306
8.18k
          if (only_selected && ! (n->flag & NODFLG_SELKEY))
307
0
            {
308
0
              current_component = NULL;
309
0
              break;
310
0
            }
311
312
8.18k
          if (DBG_PACKET)
313
8.18k
            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
8.18k
          current_component = n;
318
8.18k
          break;
319
3.22k
        case PKT_PUBLIC_SUBKEY:
320
3.22k
          if (only_selected && ! (n->flag & NODFLG_SELKEY))
321
0
            {
322
0
              current_component = NULL;
323
0
              break;
324
0
            }
325
326
3.22k
          if (DBG_PACKET)
327
3.22k
            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.22k
          current_component = n;
332
3.22k
          break;
333
21.8k
        case PKT_USER_ID:
334
21.8k
          if (only_selected && ! (n->flag & NODFLG_SELUID))
335
0
            {
336
0
              current_component = NULL;
337
0
              break;
338
0
            }
339
340
21.8k
          if (DBG_PACKET)
341
21.8k
            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
21.8k
          current_component = n;
346
21.8k
          break;
347
19.0k
        case PKT_SIGNATURE:
348
19.0k
          if (! current_component)
349
            /* The current component is not selected, don't check the
350
               sigs under it.  */
351
0
            break;
352
353
19.0k
          sig = n->pkt->pkt.signature;
354
355
19.0k
          pending_desc = xasprintf ("  sig: class: 0x%x, issuer: %s,"
356
19.0k
                                    " timestamp: %s (%lld), digest: %02x %02x",
357
19.0k
                                    sig->sig_class,
358
19.0k
                                    keystr (sig->keyid),
359
19.0k
                                    isotimestamp (sig->timestamp),
360
19.0k
                                    (long long) sig->timestamp,
361
19.0k
                                    sig->digest_start[0], sig->digest_start[1]);
362
363
364
19.0k
          if (keyid_cmp (pk_keyid (pk), sig->keyid) == 0)
365
7.59k
            issuer = pk;
366
11.4k
          else /* Issuer is a different key.  */
367
11.4k
            {
368
11.4k
              if (only_selfsigs)
369
0
                continue;
370
371
11.4k
              issuer = xtrycalloc (1, sizeof *issuer);
372
11.4k
              if (!issuer)
373
0
                err = gpg_error_from_syserror ();
374
11.4k
              else
375
11.4k
                err = get_pubkey (ctrl, issuer, sig->keyid);
376
11.4k
              if (err)
377
9.34k
                {
378
9.34k
                  xfree (issuer);
379
9.34k
                  issuer = NULL;
380
9.34k
                  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
9.34k
                  missing_issuer ++;
389
9.34k
                  break;
390
9.34k
                }
391
11.4k
            }
392
393
9.70k
          if ((err = openpgp_pk_test_algo (sig->pubkey_algo)))
394
319
            {
395
319
              if (DBG_PACKET && pending_desc)
396
319
                log_debug ("%s", pending_desc);
397
319
              log_info (_("can't check signature with unsupported"
398
319
                          " public-key algorithm (%d): %s.\n"),
399
319
                          sig->pubkey_algo, gpg_strerror (err));
400
319
              break;
401
319
            }
402
9.39k
          if ((err = openpgp_md_test_algo (sig->digest_algo)))
403
1.06k
            {
404
1.06k
              if (DBG_PACKET && pending_desc)
405
1.06k
                log_debug ("%s", pending_desc);
406
1.06k
              log_info (_("can't check signature with unsupported"
407
1.06k
                          " message-digest algorithm %d: %s.\n"),
408
1.06k
                          sig->digest_algo, gpg_strerror (err));
409
1.06k
              break;
410
1.06k
            }
411
412
          /* We iterate over the keyblock.  Most likely, the matching
413
             component is the current component so always try that
414
             first.  */
415
8.32k
          processed_current_component = 0;
416
8.32k
          for (n2 = current_component;
417
662k
               n2;
418
653k
               n2 = (processed_current_component ? n2->next : kb),
419
653k
                 processed_current_component = 1)
420
657k
            if (is_deleted_kbnode (n2))
421
0
              continue;
422
657k
            else if (processed_current_component && n2 == current_component)
423
              /* Don't process it twice.  */
424
5.16k
              continue;
425
652k
            else
426
652k
              {
427
652k
                err = check_signature_over_key_or_uid (ctrl,
428
652k
                                                       issuer, sig, kb, n2->pkt,
429
652k
                                                       NULL, NULL);
430
652k
                if (! err)
431
3.28k
                  break;
432
652k
              }
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
8.32k
          if (current_component == n2)
440
2.64k
            {
441
2.64k
              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
2.64k
              rc = 0;
448
2.64k
            }
449
5.67k
          else if (n2)
450
634
            {
451
634
              log_assert (n2->pkt->pkttype == PKT_USER_ID
452
634
                          || n2->pkt->pkttype == PKT_PUBLIC_KEY
453
634
                          || n2->pkt->pkttype == PKT_PUBLIC_SUBKEY);
454
455
634
              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
634
              log_assert (n_prevp);
476
634
              *n_prevp = n->next;
477
478
              /* Insert the sig immediately after the component.  */
479
634
              n->next = n2->next;
480
634
              n2->next = n;
481
482
634
              reordered ++;
483
634
              modified = 1;
484
485
634
              rc = 0;
486
634
            }
487
5.04k
          else
488
5.04k
            {
489
5.04k
              if (DBG_PACKET)
490
0
                {
491
0
                  log_debug ("%s", pending_desc);
492
0
                  log_debug ("    Bad signature.\n");
493
0
                }
494
495
5.04k
              if (DBG_PACKET)
496
0
                dump_sig_params = 1;
497
498
5.04k
              bad_signature ++;
499
500
5.04k
              rc = GPG_ERR_BAD_SIGNATURE;
501
5.04k
            }
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
8.32k
          {
511
8.32k
            int has_selfsig = 0;
512
8.32k
            if (! rc && issuer == pk)
513
3.25k
              {
514
3.25k
                if (n2->pkt->pkttype == PKT_PUBLIC_KEY
515
123
                    && (/* Direct key signature.  */
516
123
                        sig->sig_class == 0x1f
517
                        /* Key revocation signature.  */
518
111
                        || sig->sig_class == 0x20))
519
123
                  has_selfsig = 1;
520
3.25k
                if (n2->pkt->pkttype == PKT_PUBLIC_SUBKEY
521
511
                    && (/* Subkey binding sig.  */
522
511
                        sig->sig_class == 0x18
523
                        /* Subkey revocation sig.  */
524
30
                        || sig->sig_class == 0x28))
525
511
                  has_selfsig = 1;
526
3.25k
                if (n2->pkt->pkttype == PKT_USER_ID
527
2.62k
                    && (/* Certification sigs.  */
528
2.62k
                        sig->sig_class == 0x10
529
2.56k
                        || sig->sig_class == 0x11
530
2.56k
                        || sig->sig_class == 0x12
531
2.56k
                        || sig->sig_class == 0x13
532
                        /* Certification revocation sig.  */
533
229
                        || sig->sig_class == 0x30))
534
2.62k
                  has_selfsig = 1;
535
3.25k
              }
536
537
8.32k
            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
8.32k
            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
8.32k
          }
581
582
8.32k
          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
8.32k
          break;
610
355
        default:
611
355
          if (DBG_PACKET)
612
355
            log_debug ("unhandled packet: %d\n", p->pkttype);
613
355
          break;
614
52.6k
        }
615
52.6k
    }
616
617
8.18k
  xfree (pending_desc);
618
8.18k
  pending_desc = NULL;
619
620
8.18k
  if (issuer != pk)
621
5.07k
    free_public_key (issuer);
622
8.18k
  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
8.18k
  if (reordered)
627
408
    {
628
408
      if (remove_duplicate_sigs (kb, &dups, &modified))
629
0
        goto leave;
630
408
    }
631
632
  /* Identify keys / uids that don't have a self-sig.  */
633
8.18k
  {
634
8.18k
    int has_selfsig = 0;
635
8.18k
    PACKET *p;
636
637
8.18k
    current_component = NULL;
638
60.5k
    for (n = kb; n; n = n->next)
639
52.3k
      {
640
52.3k
        if (is_deleted_kbnode (n))
641
0
          continue;
642
643
52.3k
        p = n->pkt;
644
645
52.3k
        switch (p->pkttype)
646
52.3k
          {
647
8.18k
          case PKT_PUBLIC_KEY:
648
11.4k
          case PKT_PUBLIC_SUBKEY:
649
33.2k
          case PKT_USER_ID:
650
33.2k
            if (current_component && ! has_selfsig)
651
24.8k
              missing_selfsig ++;
652
33.2k
            current_component = n;
653
33.2k
            has_selfsig = 0;
654
33.2k
            break;
655
656
18.7k
          case PKT_SIGNATURE:
657
18.7k
            if (! current_component || has_selfsig)
658
139
              break;
659
660
18.6k
            sig = n->pkt->pkt.signature;
661
662
18.6k
            if (! (sig->flags.checked && sig->flags.valid))
663
18.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
355
          default:
694
355
            if (current_component && ! has_selfsig)
695
305
              missing_selfsig ++;
696
355
            current_component = NULL;
697
52.3k
          }
698
52.3k
      }
699
8.18k
  }
700
701
702
8.18k
 leave:
703
8.18k
  if (!opt.quiet)
704
8.18k
    {
705
8.18k
      char prefix[100];
706
8.18k
      char *p;
707
708
      /* To avoid string changes in 2.2 we strip the LF here. */
709
8.18k
      snprintf (prefix, sizeof prefix, _("key %s:\n"), pk_keyid_str (pk));
710
8.18k
      p = strrchr (prefix, '\n');
711
8.18k
      if (p)
712
8.18k
        *p = 0;
713
714
8.18k
      if (dups)
715
311
        {
716
311
          p = xtryasprintf
717
311
            (ngettext ("%d duplicate signature removed\n",
718
311
                       "%d duplicate signatures removed\n", dups), dups);
719
311
          print_info (mode, prefix, p);
720
311
          xfree (p);
721
311
        }
722
723
8.18k
      if (missing_issuer)
724
3.51k
        {
725
3.51k
          p = xtryasprintf
726
3.51k
            (ngettext ("%d signature not checked due to a missing key\n",
727
3.51k
                       "%d signatures not checked due to missing keys\n",
728
3.51k
                       missing_issuer), missing_issuer);
729
3.51k
          print_info (mode, prefix, p);
730
3.51k
          xfree (p);
731
3.51k
        }
732
8.18k
      if (bad_signature)
733
2.12k
        {
734
2.12k
          p = xtryasprintf (ngettext ("%d bad signature\n",
735
2.12k
                                      "%d bad signatures\n",
736
2.12k
                                      bad_signature), bad_signature);
737
2.12k
          print_info (mode, prefix, p);
738
2.12k
          xfree (p);
739
2.12k
        }
740
741
8.18k
      if (reordered)
742
408
        {
743
408
          p = xtryasprintf (ngettext ("%d signature reordered\n",
744
408
                                      "%d signatures reordered\n",
745
408
                                      reordered), reordered);
746
408
          print_info (mode, prefix, p);
747
408
          xfree (p);
748
408
        }
749
750
8.18k
      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
8.18k
    }
759
760
8.18k
  return modified;
761
8.18k
}