Coverage Report

Created: 2026-02-26 06:54

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