/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 | } |