/src/gnupg/g10/key-clean.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* key-clean.c - Functions to clean a keyblock |
2 | | * Copyright (C) 1998-2008, 2010-2011 Free Software Foundation, Inc. |
3 | | * Copyright (C) 2014, 2016-2018 Werner Koch |
4 | | * |
5 | | * This file is part of GnuPG. |
6 | | * |
7 | | * GnuPG is free software; you can redistribute it and/or modify |
8 | | * it under the terms of the GNU General Public License as published by |
9 | | * the Free Software Foundation; either version 3 of the License, or |
10 | | * (at your option) any later version. |
11 | | * |
12 | | * GnuPG is distributed in the hope that it will be useful, |
13 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
15 | | * GNU General Public License for more details. |
16 | | * |
17 | | * You should have received a copy of the GNU General Public License |
18 | | * along with this program; if not, see <https://www.gnu.org/licenses/>. |
19 | | * SPDX-License-Identifier: GPL-3.0-or-later |
20 | | */ |
21 | | |
22 | | #include <config.h> |
23 | | #include <stdio.h> |
24 | | #include <stdlib.h> |
25 | | #include <string.h> |
26 | | |
27 | | #include "gpg.h" |
28 | | #include "keydb.h" |
29 | | #include "../common/util.h" |
30 | | #include "../common/host2net.h" |
31 | | #include "../common/i18n.h" |
32 | | #include "options.h" |
33 | | #include "packet.h" |
34 | | #include "main.h" |
35 | | #include "key-clean.h" |
36 | | |
37 | | |
38 | | /* |
39 | | * Mark the signature of the given UID which are used to certify it. |
40 | | * To do this, we first remove all signatures which are not valid and |
41 | | * from the remaining we look for the latest one. If this is not a |
42 | | * certification revocation signature we mark the signature by setting |
43 | | * node flag bit 8. Revocations are marked with flag 11, and sigs |
44 | | * from unavailable keys are marked with flag 12. Note that flag bits |
45 | | * 9 and 10 are used for internal purposes. |
46 | | */ |
47 | | void |
48 | | mark_usable_uid_certs (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode, |
49 | | u32 *main_kid, struct key_item *klist, |
50 | | u32 curtime, u32 *next_expire) |
51 | 0 | { |
52 | 0 | kbnode_t node; |
53 | 0 | PKT_signature *sig; |
54 | | |
55 | | /* First check all signatures. */ |
56 | 0 | for (node=uidnode->next; node; node = node->next) |
57 | 0 | { |
58 | 0 | int rc; |
59 | |
|
60 | 0 | node->flag &= ~(1<<8 | 1<<9 | 1<<10 | 1<<11 | 1<<12); |
61 | 0 | if (node->pkt->pkttype == PKT_USER_ID |
62 | 0 | || node->pkt->pkttype == PKT_PUBLIC_SUBKEY |
63 | 0 | || node->pkt->pkttype == PKT_SECRET_SUBKEY) |
64 | 0 | break; /* ready */ |
65 | 0 | if (node->pkt->pkttype != PKT_SIGNATURE) |
66 | 0 | continue; |
67 | 0 | sig = node->pkt->pkt.signature; |
68 | 0 | if (main_kid |
69 | 0 | && sig->keyid[0] == main_kid[0] && sig->keyid[1] == main_kid[1]) |
70 | 0 | continue; /* ignore self-signatures if we pass in a main_kid */ |
71 | 0 | if (!IS_UID_SIG(sig) && !IS_UID_REV(sig)) |
72 | 0 | continue; /* we only look at these signature classes */ |
73 | 0 | if(sig->sig_class>=0x11 && sig->sig_class<=0x13 && |
74 | 0 | sig->sig_class-0x10<opt.min_cert_level) |
75 | 0 | continue; /* treat anything under our min_cert_level as an |
76 | | invalid signature */ |
77 | 0 | if (klist && !is_in_klist (klist, sig)) |
78 | 0 | continue; /* no need to check it then */ |
79 | 0 | if ((rc=check_key_signature (ctrl, keyblock, node, NULL))) |
80 | 0 | { |
81 | | /* we ignore anything that won't verify, but tag the |
82 | | no_pubkey case */ |
83 | 0 | if (gpg_err_code (rc) == GPG_ERR_NO_PUBKEY) |
84 | 0 | node->flag |= 1<<12; |
85 | 0 | continue; |
86 | 0 | } |
87 | 0 | node->flag |= 1<<9; |
88 | 0 | } |
89 | | /* Reset the remaining flags. */ |
90 | 0 | for (; node; node = node->next) |
91 | 0 | node->flag &= ~(1<<8 | 1<<9 | 1<<10 | 1<<11 | 1<<12); |
92 | | |
93 | | /* kbnode flag usage: bit 9 is here set for signatures to consider, |
94 | | * bit 10 will be set by the loop to keep track of keyIDs already |
95 | | * processed, bit 8 will be set for the usable signatures, and bit |
96 | | * 11 will be set for usable revocations. */ |
97 | | |
98 | | /* For each cert figure out the latest valid one. */ |
99 | 0 | for (node=uidnode->next; node; node = node->next) |
100 | 0 | { |
101 | 0 | KBNODE n, signode; |
102 | 0 | u32 kid[2]; |
103 | 0 | u32 sigdate; |
104 | |
|
105 | 0 | if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY |
106 | 0 | || node->pkt->pkttype == PKT_SECRET_SUBKEY) |
107 | 0 | break; |
108 | 0 | if ( !(node->flag & (1<<9)) ) |
109 | 0 | continue; /* not a node to look at */ |
110 | 0 | if ( (node->flag & (1<<10)) ) |
111 | 0 | continue; /* signature with a keyID already processed */ |
112 | 0 | node->flag |= (1<<10); /* mark this node as processed */ |
113 | 0 | sig = node->pkt->pkt.signature; |
114 | 0 | signode = node; |
115 | 0 | sigdate = sig->timestamp; |
116 | 0 | kid[0] = sig->keyid[0]; kid[1] = sig->keyid[1]; |
117 | | |
118 | | /* Now find the latest and greatest signature */ |
119 | 0 | for (n=uidnode->next; n; n = n->next) |
120 | 0 | { |
121 | 0 | if (n->pkt->pkttype == PKT_PUBLIC_SUBKEY |
122 | 0 | || n->pkt->pkttype == PKT_SECRET_SUBKEY) |
123 | 0 | break; |
124 | 0 | if ( !(n->flag & (1<<9)) ) |
125 | 0 | continue; |
126 | 0 | if ( (n->flag & (1<<10)) ) |
127 | 0 | continue; /* shortcut already processed signatures */ |
128 | 0 | sig = n->pkt->pkt.signature; |
129 | 0 | if (kid[0] != sig->keyid[0] || kid[1] != sig->keyid[1]) |
130 | 0 | continue; |
131 | 0 | n->flag |= (1<<10); /* mark this node as processed */ |
132 | | |
133 | | /* If signode is nonrevocable and unexpired and n isn't, |
134 | | then take signode (skip). It doesn't matter which is |
135 | | older: if signode was older then we don't want to take n |
136 | | as signode is nonrevocable. If n was older then we're |
137 | | automatically fine. */ |
138 | |
|
139 | 0 | if(((IS_UID_SIG(signode->pkt->pkt.signature) && |
140 | 0 | !signode->pkt->pkt.signature->flags.revocable && |
141 | 0 | (signode->pkt->pkt.signature->expiredate==0 || |
142 | 0 | signode->pkt->pkt.signature->expiredate>curtime))) && |
143 | 0 | (!(IS_UID_SIG(n->pkt->pkt.signature) && |
144 | 0 | !n->pkt->pkt.signature->flags.revocable && |
145 | 0 | (n->pkt->pkt.signature->expiredate==0 || |
146 | 0 | n->pkt->pkt.signature->expiredate>curtime)))) |
147 | 0 | continue; |
148 | | |
149 | | /* If n is nonrevocable and unexpired and signode isn't, |
150 | | then take n. Again, it doesn't matter which is older: if |
151 | | n was older then we don't want to take signode as n is |
152 | | nonrevocable. If signode was older then we're |
153 | | automatically fine. */ |
154 | | |
155 | 0 | if((!(IS_UID_SIG(signode->pkt->pkt.signature) && |
156 | 0 | !signode->pkt->pkt.signature->flags.revocable && |
157 | 0 | (signode->pkt->pkt.signature->expiredate==0 || |
158 | 0 | signode->pkt->pkt.signature->expiredate>curtime))) && |
159 | 0 | ((IS_UID_SIG(n->pkt->pkt.signature) && |
160 | 0 | !n->pkt->pkt.signature->flags.revocable && |
161 | 0 | (n->pkt->pkt.signature->expiredate==0 || |
162 | 0 | n->pkt->pkt.signature->expiredate>curtime)))) |
163 | 0 | { |
164 | 0 | signode = n; |
165 | 0 | sigdate = sig->timestamp; |
166 | 0 | continue; |
167 | 0 | } |
168 | | |
169 | | /* At this point, if it's newer, it goes in as the only |
170 | | remaining possibilities are signode and n are both either |
171 | | revocable or expired or both nonrevocable and unexpired. |
172 | | If the timestamps are equal take the later ordered |
173 | | packet, presuming that the key packets are hopefully in |
174 | | their original order. */ |
175 | | |
176 | 0 | if (sig->timestamp >= sigdate) |
177 | 0 | { |
178 | 0 | signode = n; |
179 | 0 | sigdate = sig->timestamp; |
180 | 0 | } |
181 | 0 | } |
182 | |
|
183 | 0 | sig = signode->pkt->pkt.signature; |
184 | 0 | if (IS_UID_SIG (sig)) |
185 | 0 | { /* this seems to be a usable one which is not revoked. |
186 | | * Just need to check whether there is an expiration time, |
187 | | * We do the expired certification after finding a suitable |
188 | | * certification, the assumption is that a signator does not |
189 | | * want that after the expiration of his certificate the |
190 | | * system falls back to an older certification which has a |
191 | | * different expiration time */ |
192 | 0 | const byte *p; |
193 | 0 | u32 expire; |
194 | |
|
195 | 0 | p = parse_sig_subpkt (sig, 1, SIGSUBPKT_SIG_EXPIRE, NULL ); |
196 | 0 | expire = p? sig->timestamp + buf32_to_u32(p) : 0; |
197 | |
|
198 | 0 | if (expire==0 || expire > curtime ) |
199 | 0 | { |
200 | 0 | signode->flag |= (1<<8); /* yeah, found a good cert */ |
201 | 0 | if (next_expire && expire && expire < *next_expire) |
202 | 0 | *next_expire = expire; |
203 | 0 | } |
204 | 0 | } |
205 | 0 | else |
206 | 0 | signode->flag |= (1<<11); |
207 | 0 | } |
208 | 0 | } |
209 | | |
210 | | |
211 | | static int |
212 | | clean_sigs_from_uid (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode, |
213 | | int noisy, int self_only) |
214 | 0 | { |
215 | 0 | int deleted = 0; |
216 | 0 | kbnode_t node; |
217 | 0 | u32 keyid[2]; |
218 | |
|
219 | 0 | log_assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY |
220 | 0 | || keyblock->pkt->pkttype == PKT_SECRET_KEY); |
221 | | |
222 | 0 | keyid_from_pk (keyblock->pkt->pkt.public_key, keyid); |
223 | | |
224 | | /* Passing in a 0 for current time here means that we'll never weed |
225 | | out an expired sig. This is correct behavior since we want to |
226 | | keep the most recent expired sig in a series. */ |
227 | 0 | mark_usable_uid_certs (ctrl, keyblock, uidnode, NULL, NULL, 0, NULL); |
228 | | |
229 | | /* What we want to do here is remove signatures that are not |
230 | | considered as part of the trust calculations. Thus, all invalid |
231 | | signatures are out, as are any signatures that aren't the last of |
232 | | a series of uid sigs or revocations It breaks down like this: |
233 | | coming out of mark_usable_uid_certs, if a sig is unflagged, it is |
234 | | not even a candidate. If a sig has flag 9 or 10, that means it |
235 | | was selected as a candidate and vetted. If a sig has flag 8 it |
236 | | is a usable signature. If a sig has flag 11 it is a usable |
237 | | revocation. If a sig has flag 12 it was issued by an unavailable |
238 | | key. "Usable" here means the most recent valid |
239 | | signature/revocation in a series from a particular signer. |
240 | | |
241 | | Delete everything that isn't a usable uid sig (which might be |
242 | | expired), a usable revocation, or a sig from an unavailable |
243 | | key. */ |
244 | |
|
245 | 0 | for (node=uidnode->next; |
246 | 0 | node && node->pkt->pkttype==PKT_SIGNATURE; |
247 | 0 | node=node->next) |
248 | 0 | { |
249 | 0 | int keep; |
250 | |
|
251 | 0 | keep = self_only? (node->pkt->pkt.signature->keyid[0] == keyid[0] |
252 | 0 | && node->pkt->pkt.signature->keyid[1] == keyid[1]) : 1; |
253 | | |
254 | | /* Keep usable uid sigs ... */ |
255 | 0 | if ((node->flag & (1<<8)) && keep) |
256 | 0 | continue; |
257 | | |
258 | | /* ... and usable revocations... */ |
259 | 0 | if ((node->flag & (1<<11)) && keep) |
260 | 0 | continue; |
261 | | |
262 | | /* ... and sigs from unavailable keys. */ |
263 | | /* disabled for now since more people seem to want sigs from |
264 | | unavailable keys removed altogether. */ |
265 | | /* |
266 | | if(node->flag & (1<<12)) |
267 | | continue; |
268 | | */ |
269 | | |
270 | | /* Everything else we delete */ |
271 | | |
272 | | /* At this point, if 12 is set, the signing key was unavailable. |
273 | | If 9 or 10 is set, it's superseded. Otherwise, it's |
274 | | invalid. */ |
275 | | |
276 | 0 | if (noisy) |
277 | 0 | log_info ("removing signature from key %s on user ID \"%s\": %s\n", |
278 | 0 | keystr (node->pkt->pkt.signature->keyid), |
279 | 0 | uidnode->pkt->pkt.user_id->name, |
280 | 0 | node->flag&(1<<12)? "key unavailable": |
281 | 0 | node->flag&(1<<9)? "signature superseded" |
282 | 0 | /* */ :"invalid signature" ); |
283 | |
|
284 | 0 | delete_kbnode (node); |
285 | 0 | deleted++; |
286 | 0 | } |
287 | |
|
288 | 0 | return deleted; |
289 | 0 | } |
290 | | |
291 | | |
292 | | /* This is substantially easier than clean_sigs_from_uid since we just |
293 | | have to establish if the uid has a valid self-sig, is not revoked, |
294 | | and is not expired. Note that this does not take into account |
295 | | whether the uid has a trust path to it - just whether the keyholder |
296 | | themselves has certified the uid. Returns true if the uid was |
297 | | compacted. To "compact" a user ID, we simply remove ALL signatures |
298 | | except the self-sig that caused the user ID to be remove-worthy. |
299 | | We don't actually remove the user ID packet itself since it might |
300 | | be resurrected in a later merge. Note that this function requires |
301 | | that the caller has already done a merge_keys_and_selfsig(). |
302 | | |
303 | | TODO: change the import code to allow importing a uid with only a |
304 | | revocation if the uid already exists on the keyring. */ |
305 | | |
306 | | static int |
307 | | clean_uid_from_key (kbnode_t keyblock, kbnode_t uidnode, int noisy) |
308 | 0 | { |
309 | 0 | kbnode_t node; |
310 | 0 | PKT_user_id *uid = uidnode->pkt->pkt.user_id; |
311 | 0 | int deleted = 0; |
312 | |
|
313 | 0 | log_assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY |
314 | 0 | || keyblock->pkt->pkttype == PKT_SECRET_KEY); |
315 | 0 | log_assert (uidnode->pkt->pkttype==PKT_USER_ID); |
316 | | |
317 | | /* Skip valid user IDs, compacted user IDs, and non-self-signed user |
318 | | IDs if --allow-non-selfsigned-uid is set. */ |
319 | 0 | if (uid->created |
320 | 0 | || uid->flags.compacted |
321 | 0 | || (!uid->flags.expired && !uid->flags.revoked && opt.allow_non_selfsigned_uid)) |
322 | 0 | return 0; |
323 | | |
324 | 0 | for (node=uidnode->next; |
325 | 0 | node && node->pkt->pkttype == PKT_SIGNATURE; |
326 | 0 | node=node->next) |
327 | 0 | { |
328 | 0 | if (!node->pkt->pkt.signature->flags.chosen_selfsig) |
329 | 0 | { |
330 | 0 | delete_kbnode (node); |
331 | 0 | deleted = 1; |
332 | 0 | uidnode->pkt->pkt.user_id->flags.compacted = 1; |
333 | 0 | } |
334 | 0 | } |
335 | |
|
336 | 0 | if (noisy) |
337 | 0 | { |
338 | 0 | const char *reason; |
339 | 0 | char *user = utf8_to_native (uid->name, uid->len, 0); |
340 | |
|
341 | 0 | if (uid->flags.revoked) |
342 | 0 | reason = _("revoked"); |
343 | 0 | else if (uid->flags.expired) |
344 | 0 | reason = _("expired"); |
345 | 0 | else |
346 | 0 | reason = _("invalid"); |
347 | |
|
348 | 0 | log_info ("compacting user ID \"%s\" on key %s: %s\n", |
349 | 0 | user, keystr_from_pk (keyblock->pkt->pkt.public_key), |
350 | 0 | reason); |
351 | |
|
352 | 0 | xfree (user); |
353 | 0 | } |
354 | |
|
355 | 0 | return deleted; |
356 | 0 | } |
357 | | |
358 | | |
359 | | /* Needs to be called after a merge_keys_and_selfsig() */ |
360 | | void |
361 | | clean_one_uid (ctrl_t ctrl, kbnode_t keyblock, kbnode_t uidnode, |
362 | | int noisy, int self_only, int *uids_cleaned, int *sigs_cleaned) |
363 | 0 | { |
364 | 0 | int dummy = 0; |
365 | |
|
366 | 0 | log_assert (keyblock->pkt->pkttype == PKT_PUBLIC_KEY |
367 | 0 | || keyblock->pkt->pkttype == PKT_SECRET_KEY); |
368 | 0 | log_assert (uidnode->pkt->pkttype==PKT_USER_ID); |
369 | | |
370 | 0 | if (!uids_cleaned) |
371 | 0 | uids_cleaned = &dummy; |
372 | |
|
373 | 0 | if (!sigs_cleaned) |
374 | 0 | sigs_cleaned = &dummy; |
375 | | |
376 | | /* Do clean_uid_from_key first since if it fires off, we don't have |
377 | | to bother with the other. */ |
378 | 0 | *uids_cleaned += clean_uid_from_key (keyblock, uidnode, noisy); |
379 | 0 | if (!uidnode->pkt->pkt.user_id->flags.compacted) |
380 | 0 | *sigs_cleaned += clean_sigs_from_uid (ctrl, keyblock, uidnode, |
381 | 0 | noisy, self_only); |
382 | 0 | } |
383 | | |
384 | | |
385 | | /* NB: This function marks the deleted nodes only and the caller is |
386 | | * responsible to skip or remove them. Needs to be called after a |
387 | | * merge_keys_and_selfsig(). */ |
388 | | void |
389 | | clean_all_uids (ctrl_t ctrl, kbnode_t keyblock, int noisy, int self_only, |
390 | | int *uids_cleaned, int *sigs_cleaned) |
391 | 0 | { |
392 | 0 | kbnode_t node; |
393 | |
|
394 | 0 | for (node = keyblock->next; |
395 | 0 | node && !(node->pkt->pkttype == PKT_PUBLIC_SUBKEY |
396 | 0 | || node->pkt->pkttype == PKT_SECRET_SUBKEY); |
397 | 0 | node = node->next) |
398 | 0 | { |
399 | 0 | if (node->pkt->pkttype == PKT_USER_ID) |
400 | 0 | clean_one_uid (ctrl, keyblock, node, noisy, self_only, |
401 | 0 | uids_cleaned, sigs_cleaned); |
402 | 0 | } |
403 | | |
404 | | /* Remove bogus subkey binding signatures: The only signatures |
405 | | * allowed are of class 0x18 and 0x28. */ |
406 | 0 | log_assert (!node || (node->pkt->pkttype == PKT_PUBLIC_SUBKEY |
407 | 0 | || node->pkt->pkttype == PKT_SECRET_SUBKEY)); |
408 | 0 | } |
409 | | |
410 | | |
411 | | /* Helper for clean_all_subkeys. */ |
412 | | static int |
413 | | clean_one_subkey (ctrl_t ctrl, kbnode_t subkeynode, int noisy, int clean_level) |
414 | 0 | { |
415 | 0 | kbnode_t node; |
416 | 0 | PKT_public_key *pk = subkeynode->pkt->pkt.public_key; |
417 | 0 | unsigned int use = pk->pubkey_usage; |
418 | 0 | int do_clean = 0; |
419 | |
|
420 | 0 | (void)ctrl; |
421 | 0 | (void)noisy; |
422 | |
|
423 | 0 | log_assert (subkeynode->pkt->pkttype == PKT_PUBLIC_SUBKEY |
424 | 0 | || subkeynode->pkt->pkttype == PKT_SECRET_SUBKEY); |
425 | | |
426 | 0 | if (DBG_LOOKUP) |
427 | 0 | log_debug ("\tchecking subkey %08lX [%c%c%c%c%c]\n", |
428 | 0 | (ulong) keyid_from_pk (pk, NULL), |
429 | 0 | (use & PUBKEY_USAGE_ENC)? 'e':'-', |
430 | 0 | (use & PUBKEY_USAGE_SIG)? 's':'-', |
431 | 0 | (use & PUBKEY_USAGE_CERT)? 'c':'-', |
432 | 0 | (use & PUBKEY_USAGE_AUTH)? 'a':'-', |
433 | 0 | (use & PUBKEY_USAGE_UNKNOWN)? '?':'-'); |
434 | |
|
435 | 0 | if (!pk->flags.valid) |
436 | 0 | { |
437 | 0 | if (DBG_LOOKUP) |
438 | 0 | log_debug ("\tsubkey not valid\n"); |
439 | 0 | if (clean_level == KEY_CLEAN_INVALID) |
440 | 0 | do_clean = 1; |
441 | 0 | } |
442 | 0 | if (pk->has_expired) |
443 | 0 | { |
444 | 0 | if (DBG_LOOKUP) |
445 | 0 | log_debug ("\tsubkey has expired\n"); |
446 | 0 | if (clean_level == KEY_CLEAN_ALL) |
447 | 0 | do_clean = 1; |
448 | 0 | else if (clean_level == KEY_CLEAN_AUTHENCR |
449 | 0 | && (use & (PUBKEY_USAGE_ENC | PUBKEY_USAGE_AUTH)) |
450 | 0 | && !(use & (PUBKEY_USAGE_SIG | PUBKEY_USAGE_CERT))) |
451 | 0 | do_clean = 1; |
452 | 0 | else if (clean_level == KEY_CLEAN_ENCR |
453 | 0 | && (use & PUBKEY_USAGE_ENC) |
454 | 0 | && !(use & (PUBKEY_USAGE_SIG | PUBKEY_USAGE_CERT |
455 | 0 | | PUBKEY_USAGE_AUTH))) |
456 | 0 | do_clean = 1; |
457 | 0 | } |
458 | 0 | if (pk->flags.revoked) |
459 | 0 | { |
460 | 0 | if (DBG_LOOKUP) |
461 | 0 | log_debug ("\tsubkey has been revoked (keeping)\n"); |
462 | | /* Avoid any cleaning because revocations are important. */ |
463 | 0 | do_clean = 0; |
464 | 0 | } |
465 | 0 | if (!do_clean) |
466 | 0 | return 0; |
467 | | |
468 | 0 | if (DBG_LOOKUP) |
469 | 0 | log_debug ("\t=> removing this subkey\n"); |
470 | |
|
471 | 0 | delete_kbnode (subkeynode); |
472 | 0 | for (node = subkeynode->next; |
473 | 0 | node && !(node->pkt->pkttype == PKT_PUBLIC_SUBKEY |
474 | 0 | || node->pkt->pkttype == PKT_SECRET_SUBKEY); |
475 | 0 | node = node->next) |
476 | 0 | delete_kbnode (node); |
477 | |
|
478 | 0 | return 1; |
479 | 0 | } |
480 | | |
481 | | |
482 | | /* Helper for clean_all_subkeys. Here duplicate signatures from a |
483 | | * subkey are removed. This should in general not happen because |
484 | | * import takes care of that. However, sometimes other tools are used |
485 | | * to manage a keyring or key has been imported a long time ago. */ |
486 | | static int |
487 | | clean_one_subkey_dupsigs (ctrl_t ctrl, kbnode_t subkeynode) |
488 | 0 | { |
489 | 0 | kbnode_t node; |
490 | 0 | PKT_public_key *pk = subkeynode->pkt->pkt.public_key; |
491 | 0 | int any_choosen = 0; |
492 | 0 | int count = 0; |
493 | |
|
494 | 0 | (void)ctrl; |
495 | |
|
496 | 0 | log_assert (subkeynode->pkt->pkttype == PKT_PUBLIC_SUBKEY |
497 | 0 | || subkeynode->pkt->pkttype == PKT_SECRET_SUBKEY); |
498 | | |
499 | 0 | if (DBG_LOOKUP) |
500 | 0 | log_debug ("\tchecking subkey %08lX for dupsigs\n", |
501 | 0 | (ulong) keyid_from_pk (pk, NULL)); |
502 | | |
503 | | /* First check that the chosen flag has been set. Note that we |
504 | | * only look at plain signatures so to keep all revocation |
505 | | * signatures which may carry important information. */ |
506 | 0 | for (node = subkeynode->next; |
507 | 0 | node && !(node->pkt->pkttype == PKT_PUBLIC_SUBKEY |
508 | 0 | || node->pkt->pkttype == PKT_SECRET_SUBKEY); |
509 | 0 | node = node->next) |
510 | 0 | { |
511 | 0 | if (!is_deleted_kbnode (node) |
512 | 0 | && node->pkt->pkttype == PKT_SIGNATURE |
513 | 0 | && IS_SUBKEY_SIG (node->pkt->pkt.signature) |
514 | 0 | && node->pkt->pkt.signature->flags.chosen_selfsig) |
515 | 0 | { |
516 | 0 | any_choosen = 1; |
517 | 0 | break; |
518 | 0 | } |
519 | 0 | } |
520 | |
|
521 | 0 | if (!any_choosen) |
522 | 0 | return 0; /* Ooops no chosen flag set - we can't decide. */ |
523 | | |
524 | 0 | for (node = subkeynode->next; |
525 | 0 | node && !(node->pkt->pkttype == PKT_PUBLIC_SUBKEY |
526 | 0 | || node->pkt->pkttype == PKT_SECRET_SUBKEY); |
527 | 0 | node = node->next) |
528 | 0 | { |
529 | 0 | if (!is_deleted_kbnode (node) |
530 | 0 | && node->pkt->pkttype == PKT_SIGNATURE |
531 | 0 | && IS_SUBKEY_SIG (node->pkt->pkt.signature) |
532 | 0 | && !node->pkt->pkt.signature->flags.chosen_selfsig) |
533 | 0 | { |
534 | 0 | delete_kbnode (node); |
535 | 0 | count++; |
536 | 0 | } |
537 | 0 | } |
538 | |
|
539 | 0 | return count; |
540 | 0 | } |
541 | | |
542 | | |
543 | | /* This function only marks the deleted nodes and the caller is |
544 | | * responsible to skip or remove them. Needs to be called after a |
545 | | * merge_keys_and_selfsig. CLEAN_LEVEL is one of the KEY_CLEAN_* |
546 | | * values. */ |
547 | | void |
548 | | clean_all_subkeys (ctrl_t ctrl, kbnode_t keyblock, int noisy, int clean_level, |
549 | | int *subkeys_cleaned, int *sigs_cleaned) |
550 | 0 | { |
551 | 0 | kbnode_t first_subkey, node; |
552 | 0 | int n; |
553 | |
|
554 | 0 | if (DBG_LOOKUP) |
555 | 0 | log_debug ("clean_all_subkeys: checking key %08lX\n", |
556 | 0 | (ulong) keyid_from_pk (keyblock->pkt->pkt.public_key, NULL)); |
557 | |
|
558 | 0 | for (node = keyblock->next; node; node = node->next) |
559 | 0 | if (!is_deleted_kbnode (node) |
560 | 0 | && (node->pkt->pkttype == PKT_PUBLIC_SUBKEY |
561 | 0 | || node->pkt->pkttype == PKT_SECRET_SUBKEY)) |
562 | 0 | break; |
563 | 0 | first_subkey = node; |
564 | | |
565 | | /* Remove bogus subkey binding signatures: The only signatures |
566 | | * allowed are of class 0x18 and 0x28. */ |
567 | 0 | for (node = first_subkey; node; node = node->next) |
568 | 0 | { |
569 | 0 | if (is_deleted_kbnode (node)) |
570 | 0 | continue; |
571 | 0 | if (node->pkt->pkttype == PKT_SIGNATURE |
572 | 0 | && !(IS_SUBKEY_SIG (node->pkt->pkt.signature) |
573 | 0 | || IS_SUBKEY_REV (node->pkt->pkt.signature))) |
574 | 0 | { |
575 | 0 | delete_kbnode (node); |
576 | 0 | if (sigs_cleaned) |
577 | 0 | ++*sigs_cleaned; |
578 | 0 | } |
579 | 0 | } |
580 | | |
581 | | /* Do the selected cleaning. */ |
582 | 0 | if (clean_level > KEY_CLEAN_NONE) |
583 | 0 | { |
584 | | /* Clean enitre subkeys. */ |
585 | 0 | for (node = first_subkey; node; node = node->next) |
586 | 0 | { |
587 | 0 | if (is_deleted_kbnode (node)) |
588 | 0 | continue; |
589 | 0 | if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY |
590 | 0 | || node->pkt->pkttype == PKT_SECRET_SUBKEY) |
591 | 0 | { |
592 | 0 | if (clean_one_subkey (ctrl, node, noisy, clean_level)) |
593 | 0 | { |
594 | 0 | if (subkeys_cleaned) |
595 | 0 | ++*subkeys_cleaned; |
596 | 0 | } |
597 | 0 | } |
598 | 0 | } |
599 | | |
600 | | /* Clean duplicate signatures from a subkey. */ |
601 | 0 | for (node = first_subkey; node; node = node->next) |
602 | 0 | { |
603 | 0 | if (is_deleted_kbnode (node)) |
604 | 0 | continue; |
605 | 0 | if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY |
606 | 0 | || node->pkt->pkttype == PKT_SECRET_SUBKEY) |
607 | 0 | { |
608 | 0 | n = clean_one_subkey_dupsigs (ctrl, node); |
609 | 0 | if (sigs_cleaned) |
610 | 0 | *sigs_cleaned += n; |
611 | 0 | } |
612 | 0 | } |
613 | 0 | } |
614 | 0 | } |