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