Line | Count | Source (jump to first uncovered line) |
1 | | /* trustdb.c |
2 | | * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, |
3 | | * 2008, 2012 Free Software Foundation, Inc. |
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 | | */ |
20 | | |
21 | | #include <config.h> |
22 | | #include <stdio.h> |
23 | | #include <stdlib.h> |
24 | | #include <string.h> |
25 | | |
26 | | #include "gpg.h" |
27 | | #include "../common/status.h" |
28 | | #include "../common/iobuf.h" |
29 | | #include "../regexp/jimregexp.h" |
30 | | #include "keydb.h" |
31 | | #include "../common/util.h" |
32 | | #include "options.h" |
33 | | #include "packet.h" |
34 | | #include "main.h" |
35 | | #include "../common/mbox-util.h" |
36 | | #include "../common/i18n.h" |
37 | | #include "tdbio.h" |
38 | | #include "trustdb.h" |
39 | | #include "tofu.h" |
40 | | #include "key-clean.h" |
41 | | |
42 | | static void write_record (ctrl_t ctrl, TRUSTREC *rec); |
43 | | static void do_sync(void); |
44 | | |
45 | | |
46 | | |
47 | | static u32 |
48 | | keyid_from_fpr20 (ctrl_t ctrl, const byte *fpr, u32 *keyid) |
49 | 0 | { |
50 | 0 | u32 dummy_keyid[2]; |
51 | 0 | int fprlen; |
52 | |
|
53 | 0 | if( !keyid ) |
54 | 0 | keyid = dummy_keyid; |
55 | | |
56 | | /* Problem: We do only use fingerprints in the trustdb but |
57 | | * we need the keyID here to indetify the key; we can only |
58 | | * use that ugly hack to distinguish between 16 and 20 |
59 | | * bytes fpr - it does not work always so we better change |
60 | | * the whole validation code to only work with |
61 | | * fingerprints */ |
62 | 0 | fprlen = (!fpr[16] && !fpr[17] && !fpr[18] && !fpr[19])? 16:20; |
63 | |
|
64 | 0 | if (fprlen != 20) |
65 | 0 | { |
66 | | /* This is special as we have to lookup the key first. */ |
67 | 0 | PKT_public_key pk; |
68 | 0 | int rc; |
69 | |
|
70 | 0 | memset (&pk, 0, sizeof pk); |
71 | 0 | rc = get_pubkey_byfprint (ctrl, &pk, NULL, fpr, fprlen); |
72 | 0 | if (rc) |
73 | 0 | { |
74 | 0 | log_printhex (fpr, fprlen, |
75 | 0 | "Oops: keyid_from_fingerprint: no pubkey; fpr:"); |
76 | 0 | keyid[0] = 0; |
77 | 0 | keyid[1] = 0; |
78 | 0 | } |
79 | 0 | else |
80 | 0 | keyid_from_pk (&pk, keyid); |
81 | 0 | } |
82 | 0 | else |
83 | 0 | { |
84 | 0 | keyid[0] = buf32_to_u32 (fpr+12); |
85 | 0 | keyid[1] = buf32_to_u32 (fpr+16); |
86 | 0 | } |
87 | |
|
88 | 0 | return keyid[1]; |
89 | 0 | } |
90 | | |
91 | | typedef struct key_item **KeyHashTable; /* see new_key_hash_table() */ |
92 | | |
93 | | /* |
94 | | * Structure to keep track of keys, this is used as an array wherre |
95 | | * the item right after the last one has a keyblock set to NULL. |
96 | | * Maybe we can drop this thing and replace it by key_item |
97 | | */ |
98 | | struct key_array |
99 | | { |
100 | | KBNODE keyblock; |
101 | | }; |
102 | | |
103 | | |
104 | | /* Control information for the trust DB. */ |
105 | | static struct |
106 | | { |
107 | | int init; |
108 | | int level; |
109 | | char *dbname; |
110 | | int no_trustdb; |
111 | | } trustdb_args; |
112 | | |
113 | | /* Some globals. */ |
114 | | static struct key_item *user_utk_list; /* temp. used to store --trusted-keys */ |
115 | | static struct key_item *utk_list; /* all ultimately trusted keys */ |
116 | | |
117 | | static int pending_check_trustdb; |
118 | | |
119 | | static int validate_keys (ctrl_t ctrl, int interactive); |
120 | | |
121 | | |
122 | | /********************************************** |
123 | | ************* some helpers ******************* |
124 | | **********************************************/ |
125 | | |
126 | | static struct key_item * |
127 | | new_key_item (void) |
128 | 0 | { |
129 | 0 | struct key_item *k; |
130 | |
|
131 | 0 | k = xmalloc_clear (sizeof *k); |
132 | 0 | return k; |
133 | 0 | } |
134 | | |
135 | | static void |
136 | | release_key_items (struct key_item *k) |
137 | 6.14k | { |
138 | 6.14k | struct key_item *k2; |
139 | | |
140 | 6.14k | for (; k; k = k2) |
141 | 0 | { |
142 | 0 | k2 = k->next; |
143 | 0 | xfree (k->trust_regexp); |
144 | 0 | xfree (k); |
145 | 0 | } |
146 | 6.14k | } |
147 | | |
148 | 6.15k | #define KEY_HASH_TABLE_SIZE 1024 |
149 | | |
150 | | /* |
151 | | * For fast keylook up we need a hash table. Each byte of a KeyID |
152 | | * should be distributed equally over the 256 possible values (except |
153 | | * for v3 keyIDs but we consider them as not important here). So we |
154 | | * can just use 10 bits to index a table of KEY_HASH_TABLE_SIZE key items. |
155 | | * Possible optimization: Do not use key_items but other hash_table when the |
156 | | * duplicates lists get too large. |
157 | | */ |
158 | | static KeyHashTable |
159 | | new_key_hash_table (void) |
160 | 6 | { |
161 | 6 | struct key_item **tbl; |
162 | | |
163 | 6 | tbl = xmalloc_clear (KEY_HASH_TABLE_SIZE * sizeof *tbl); |
164 | 6 | return tbl; |
165 | 6 | } |
166 | | |
167 | | static void |
168 | | release_key_hash_table (KeyHashTable tbl) |
169 | 6 | { |
170 | 6 | int i; |
171 | | |
172 | 6 | if (!tbl) |
173 | 0 | return; |
174 | 6.15k | for (i=0; i < KEY_HASH_TABLE_SIZE; i++) |
175 | 6.14k | release_key_items (tbl[i]); |
176 | 6 | xfree (tbl); |
177 | 6 | } |
178 | | |
179 | | /* |
180 | | * Returns: True if the keyID is in the given hash table |
181 | | */ |
182 | | static int |
183 | | test_key_hash_table (KeyHashTable tbl, u32 *kid) |
184 | 0 | { |
185 | 0 | struct key_item *k; |
186 | |
|
187 | 0 | for (k = tbl[(kid[1] % KEY_HASH_TABLE_SIZE)]; k; k = k->next) |
188 | 0 | if (k->kid[0] == kid[0] && k->kid[1] == kid[1]) |
189 | 0 | return 1; |
190 | 0 | return 0; |
191 | 0 | } |
192 | | |
193 | | /* |
194 | | * Add a new key to the hash table. The key is identified by its key ID. |
195 | | */ |
196 | | static void |
197 | | add_key_hash_table (KeyHashTable tbl, u32 *kid) |
198 | 0 | { |
199 | 0 | int i = kid[1] % KEY_HASH_TABLE_SIZE; |
200 | 0 | struct key_item *k, *kk; |
201 | |
|
202 | 0 | for (k = tbl[i]; k; k = k->next) |
203 | 0 | if (k->kid[0] == kid[0] && k->kid[1] == kid[1]) |
204 | 0 | return; /* already in table */ |
205 | | |
206 | 0 | kk = new_key_item (); |
207 | 0 | kk->kid[0] = kid[0]; |
208 | 0 | kk->kid[1] = kid[1]; |
209 | 0 | kk->next = tbl[i]; |
210 | 0 | tbl[i] = kk; |
211 | 0 | } |
212 | | |
213 | | /* |
214 | | * Release a key_array |
215 | | */ |
216 | | static void |
217 | | release_key_array ( struct key_array *keys ) |
218 | 2 | { |
219 | 2 | struct key_array *k; |
220 | | |
221 | 2 | if (keys) { |
222 | 0 | for (k=keys; k->keyblock; k++) |
223 | 0 | release_kbnode (k->keyblock); |
224 | 0 | xfree (keys); |
225 | 0 | } |
226 | 2 | } |
227 | | |
228 | | |
229 | | /********************************************* |
230 | | ********** Initialization ***************** |
231 | | *********************************************/ |
232 | | |
233 | | |
234 | | |
235 | | /* |
236 | | * Used to register extra ultimately trusted keys - this has to be done |
237 | | * before initializing the validation module. |
238 | | * FIXME: Should be replaced by a function to add those keys to the trustdb. |
239 | | */ |
240 | | static void |
241 | | tdb_register_trusted_keyid (u32 *keyid) |
242 | 0 | { |
243 | 0 | struct key_item *k; |
244 | |
|
245 | 0 | k = new_key_item (); |
246 | 0 | k->kid[0] = keyid[0]; |
247 | 0 | k->kid[1] = keyid[1]; |
248 | 0 | k->next = user_utk_list; |
249 | 0 | user_utk_list = k; |
250 | 0 | } |
251 | | |
252 | | |
253 | | void |
254 | | tdb_register_trusted_key (const char *string) |
255 | 0 | { |
256 | 0 | gpg_error_t err; |
257 | 0 | KEYDB_SEARCH_DESC desc; |
258 | 0 | u32 kid[2]; |
259 | |
|
260 | 0 | err = classify_user_id (string, &desc, 1); |
261 | 0 | if (!err) |
262 | 0 | { |
263 | 0 | if (desc.mode == KEYDB_SEARCH_MODE_LONG_KID) |
264 | 0 | { |
265 | 0 | tdb_register_trusted_keyid (desc.u.kid); |
266 | 0 | return; |
267 | 0 | } |
268 | 0 | if (desc.mode == KEYDB_SEARCH_MODE_FPR && desc.fprlen == 20) |
269 | 0 | { |
270 | 0 | kid[0] = buf32_to_u32 (desc.u.fpr+12); |
271 | 0 | kid[1] = buf32_to_u32 (desc.u.fpr+16); |
272 | 0 | tdb_register_trusted_keyid (kid); |
273 | 0 | return; |
274 | 0 | } |
275 | 0 | if (desc.mode == KEYDB_SEARCH_MODE_FPR && desc.fprlen == 32) |
276 | 0 | { |
277 | 0 | kid[0] = buf32_to_u32 (desc.u.fpr); |
278 | 0 | kid[1] = buf32_to_u32 (desc.u.fpr+4); |
279 | 0 | tdb_register_trusted_keyid (kid); |
280 | 0 | return; |
281 | 0 | } |
282 | 0 | } |
283 | 0 | log_error (_("'%s' is not a valid long keyID\n"), string ); |
284 | 0 | } |
285 | | |
286 | | |
287 | | /* |
288 | | * Helper to add a key to the global list of ultimately trusted keys. |
289 | | * Returns: true = inserted, false = already in list. |
290 | | */ |
291 | | static int |
292 | | add_utk (u32 *kid) |
293 | 0 | { |
294 | 0 | struct key_item *k; |
295 | |
|
296 | 0 | if (tdb_keyid_is_utk (kid)) |
297 | 0 | return 0; |
298 | | |
299 | 0 | k = new_key_item (); |
300 | 0 | k->kid[0] = kid[0]; |
301 | 0 | k->kid[1] = kid[1]; |
302 | 0 | k->ownertrust = TRUST_ULTIMATE; |
303 | 0 | k->next = utk_list; |
304 | 0 | utk_list = k; |
305 | 0 | if( opt.verbose > 1 ) |
306 | 0 | log_info(_("key %s: accepted as trusted key\n"), keystr(kid)); |
307 | 0 | return 1; |
308 | 0 | } |
309 | | |
310 | | |
311 | | /* Add/remove KID to/from the list of ultimately trusted keys. */ |
312 | | void |
313 | | tdb_update_utk (u32 *kid, int add) |
314 | 0 | { |
315 | 0 | struct key_item *k, *k_prev; |
316 | |
|
317 | 0 | k_prev = NULL; |
318 | 0 | for (k = utk_list; k; k = k->next) |
319 | 0 | if (k->kid[0] == kid[0] && k->kid[1] == kid[1]) |
320 | 0 | break; |
321 | 0 | else |
322 | 0 | k_prev = k; |
323 | |
|
324 | 0 | if (add) |
325 | 0 | { |
326 | 0 | if (!k) |
327 | 0 | { |
328 | 0 | k = new_key_item (); |
329 | 0 | k->kid[0] = kid[0]; |
330 | 0 | k->kid[1] = kid[1]; |
331 | 0 | k->ownertrust = TRUST_ULTIMATE; |
332 | 0 | k->next = utk_list; |
333 | 0 | utk_list = k; |
334 | 0 | if ( opt.verbose > 1 ) |
335 | 0 | log_info(_("key %s: accepted as trusted key\n"), keystr(kid)); |
336 | 0 | } |
337 | 0 | } |
338 | 0 | else |
339 | 0 | { |
340 | 0 | if (k) |
341 | 0 | { |
342 | 0 | if (k_prev) |
343 | 0 | k_prev->next = k->next; |
344 | 0 | else |
345 | 0 | utk_list = NULL; |
346 | |
|
347 | 0 | xfree (k->trust_regexp); |
348 | 0 | xfree (k); |
349 | 0 | } |
350 | 0 | } |
351 | 0 | } |
352 | | |
353 | | |
354 | | /**************** |
355 | | * Verify that all our secret keys are usable and put them into the utk_list. |
356 | | */ |
357 | | static void |
358 | | verify_own_keys (ctrl_t ctrl) |
359 | 1 | { |
360 | 1 | TRUSTREC rec; |
361 | 1 | ulong recnum; |
362 | 1 | int rc; |
363 | 1 | struct key_item *k, *k2; |
364 | 1 | int need_revalidation = 0; |
365 | | |
366 | 1 | if (utk_list) |
367 | 0 | return; /* Has already been run. */ |
368 | | |
369 | | /* scan the trustdb to find all ultimately trusted keys */ |
370 | 30 | for (recnum=1; !tdbio_read_record (recnum, &rec, 0); recnum++ ) |
371 | 29 | { |
372 | 29 | if (rec.rectype == RECTYPE_TRUST |
373 | 29 | && (rec.r.trust.ownertrust & TRUST_MASK) == TRUST_ULTIMATE) |
374 | 0 | { |
375 | 0 | u32 kid[2]; |
376 | |
|
377 | 0 | keyid_from_fpr20 (ctrl, rec.r.trust.fingerprint, kid); |
378 | 0 | if (!add_utk (kid)) |
379 | 0 | log_info (_("key %s occurs more than once in the trustdb\n"), |
380 | 0 | keystr(kid)); |
381 | 0 | else if ((rec.r.trust.flags & 1)) |
382 | 0 | { |
383 | | /* Record marked as inserted via --trusted-key. Is this |
384 | | * still the case? */ |
385 | 0 | for (k2 = user_utk_list; k2; k2 = k2->next) |
386 | 0 | if (k2->kid[0] == kid[0] && k2->kid[1] == kid[1]) |
387 | 0 | break; |
388 | 0 | if (!k2) /* No - clear the flag. */ |
389 | 0 | { |
390 | 0 | if (DBG_TRUST) |
391 | 0 | log_debug ("clearing former --trusted-key %s\n", |
392 | 0 | keystr (kid)); |
393 | 0 | rec.r.trust.ownertrust = TRUST_UNKNOWN; |
394 | 0 | rec.r.trust.flags &= ~(rec.r.trust.flags & 1); |
395 | 0 | write_record (ctrl, &rec); |
396 | 0 | need_revalidation = 1; |
397 | 0 | } |
398 | 0 | } |
399 | 0 | } |
400 | 29 | } |
401 | | |
402 | 1 | if (need_revalidation) |
403 | 0 | { |
404 | 0 | tdb_revalidation_mark (ctrl); |
405 | 0 | do_sync (); |
406 | 0 | } |
407 | | |
408 | | /* Put any --trusted-key keys into the trustdb */ |
409 | 1 | for (k = user_utk_list; k; k = k->next) |
410 | 0 | { |
411 | 0 | if ( add_utk (k->kid) ) |
412 | 0 | { /* not yet in trustDB as ultimately trusted */ |
413 | 0 | PKT_public_key pk; |
414 | |
|
415 | 0 | memset (&pk, 0, sizeof pk); |
416 | 0 | rc = get_pubkey_with_ldap_fallback (ctrl, &pk, k->kid); |
417 | 0 | if (rc) |
418 | 0 | log_info(_("key %s: no public key for trusted key - skipped\n"), |
419 | 0 | keystr(k->kid)); |
420 | 0 | else |
421 | 0 | { |
422 | 0 | tdb_update_ownertrust |
423 | 0 | (ctrl, &pk, ((tdb_get_ownertrust (ctrl, &pk, 0) & ~TRUST_MASK) |
424 | 0 | | TRUST_ULTIMATE ), 1); |
425 | 0 | release_public_key_parts (&pk); |
426 | 0 | } |
427 | |
|
428 | 0 | if (!opt.quiet) |
429 | 0 | log_info (_("key %s marked as ultimately trusted\n"), |
430 | 0 | keystr(k->kid)); |
431 | 0 | } |
432 | 0 | } |
433 | | |
434 | | /* release the helper table table */ |
435 | 1 | release_key_items (user_utk_list); |
436 | 1 | user_utk_list = NULL; |
437 | 1 | return; |
438 | 1 | } |
439 | | |
440 | | /* Returns whether KID is on the list of ultimately trusted keys. */ |
441 | | int |
442 | | tdb_keyid_is_utk (u32 *kid) |
443 | 0 | { |
444 | 0 | struct key_item *k; |
445 | |
|
446 | 0 | for (k = utk_list; k; k = k->next) |
447 | 0 | if (k->kid[0] == kid[0] && k->kid[1] == kid[1]) |
448 | 0 | return 1; |
449 | | |
450 | 0 | return 0; |
451 | 0 | } |
452 | | |
453 | | /* Return the list of ultimately trusted keys. */ |
454 | | struct key_item * |
455 | | tdb_utks (void) |
456 | 0 | { |
457 | 0 | return utk_list; |
458 | 0 | } |
459 | | |
460 | | /********************************************* |
461 | | *********** TrustDB stuff ******************* |
462 | | *********************************************/ |
463 | | |
464 | | /* |
465 | | * Read a record but die if it does not exist |
466 | | */ |
467 | | static void |
468 | | read_record (ulong recno, TRUSTREC *rec, int rectype ) |
469 | 0 | { |
470 | 0 | int rc = tdbio_read_record (recno, rec, rectype); |
471 | 0 | if (rc) |
472 | 0 | { |
473 | 0 | log_error(_("trust record %lu, req type %d: read failed: %s\n"), |
474 | 0 | recno, rec->rectype, gpg_strerror (rc) ); |
475 | 0 | tdbio_invalid(); |
476 | 0 | } |
477 | 0 | if (rectype != rec->rectype) |
478 | 0 | { |
479 | 0 | log_error(_("trust record %lu is not of requested type %d\n"), |
480 | 0 | rec->recnum, rectype); |
481 | 0 | tdbio_invalid(); |
482 | 0 | } |
483 | 0 | } |
484 | | |
485 | | /* |
486 | | * Write a record and die on error |
487 | | */ |
488 | | static void |
489 | | write_record (ctrl_t ctrl, TRUSTREC *rec) |
490 | 0 | { |
491 | 0 | int rc = tdbio_write_record (ctrl, rec); |
492 | 0 | if (rc) |
493 | 0 | { |
494 | 0 | log_error(_("trust record %lu, type %d: write failed: %s\n"), |
495 | 0 | rec->recnum, rec->rectype, gpg_strerror (rc) ); |
496 | 0 | tdbio_invalid(); |
497 | 0 | } |
498 | 0 | } |
499 | | |
500 | | /* |
501 | | * sync the TrustDb and die on error |
502 | | */ |
503 | | static void |
504 | | do_sync(void) |
505 | 4 | { |
506 | 4 | int rc = tdbio_sync (); |
507 | 4 | if(rc) |
508 | 0 | { |
509 | 0 | log_error (_("trustdb: sync failed: %s\n"), gpg_strerror (rc) ); |
510 | 0 | g10_exit(2); |
511 | 0 | } |
512 | 4 | } |
513 | | |
514 | | const char * |
515 | | trust_model_string (int model) |
516 | 0 | { |
517 | 0 | switch (model) |
518 | 0 | { |
519 | 0 | case TM_CLASSIC: return "classic"; |
520 | 0 | case TM_PGP: return "pgp"; |
521 | 0 | case TM_EXTERNAL: return "external"; |
522 | 0 | case TM_TOFU: return "tofu"; |
523 | 0 | case TM_TOFU_PGP: return "tofu+pgp"; |
524 | 0 | case TM_ALWAYS: return "always"; |
525 | 0 | case TM_DIRECT: return "direct"; |
526 | 0 | default: return "unknown"; |
527 | 0 | } |
528 | 0 | } |
529 | | |
530 | | /**************** |
531 | | * Perform some checks over the trustdb |
532 | | * level 0: only open the db |
533 | | * 1: used for initial program startup |
534 | | */ |
535 | | int |
536 | | setup_trustdb( int level, const char *dbname ) |
537 | 1 | { |
538 | | /* just store the args */ |
539 | 1 | if( trustdb_args.init ) |
540 | 0 | return 0; |
541 | 1 | trustdb_args.level = level; |
542 | 1 | trustdb_args.dbname = dbname? xstrdup(dbname): NULL; |
543 | 1 | return 0; |
544 | 1 | } |
545 | | |
546 | | void |
547 | | how_to_fix_the_trustdb (void) |
548 | 0 | { |
549 | 0 | const char *name = trustdb_args.dbname; |
550 | |
|
551 | 0 | if (!name) |
552 | 0 | name = "trustdb.gpg"; |
553 | |
|
554 | 0 | log_info (_("You may try to re-create the trustdb using the commands:\n")); |
555 | 0 | log_info (" cd %s\n", gnupg_homedir ()); |
556 | 0 | log_info (" %s --export-ownertrust > otrust.tmp\n", GPG_NAME); |
557 | | #ifdef HAVE_W32_SYSTEM |
558 | | log_info (" del %s\n", name); |
559 | | #else |
560 | 0 | log_info (" rm %s\n", name); |
561 | 0 | #endif |
562 | 0 | log_info (" %s --import-ownertrust < otrust.tmp\n", GPG_NAME); |
563 | 0 | log_info (_("If that does not work, please consult the manual\n")); |
564 | 0 | } |
565 | | |
566 | | |
567 | | /* Initialize the trustdb. With NO_CREATE set a missing trustdb is |
568 | | * not an error and the function won't terminate the process on error; |
569 | | * in that case 0 is returned if there is a trustdb or an error code |
570 | | * if no trustdb is available. */ |
571 | | gpg_error_t |
572 | | init_trustdb (ctrl_t ctrl, int no_create) |
573 | 18 | { |
574 | 18 | int level = trustdb_args.level; |
575 | 18 | const char* dbname = trustdb_args.dbname; |
576 | | |
577 | 18 | if( trustdb_args.init ) |
578 | 17 | return 0; |
579 | | |
580 | 1 | trustdb_args.init = 1; |
581 | | |
582 | 1 | if(level==0 || level==1) |
583 | 1 | { |
584 | 1 | int rc = tdbio_set_dbname (ctrl, dbname, (!no_create && level), |
585 | 1 | &trustdb_args.no_trustdb); |
586 | 1 | if (no_create && trustdb_args.no_trustdb) |
587 | 0 | { |
588 | | /* No trustdb found and the caller asked us not to create |
589 | | * it. Return an error and set the initialization state |
590 | | * back so that we always test for an existing trustdb. */ |
591 | 0 | trustdb_args.init = 0; |
592 | 0 | return gpg_error (GPG_ERR_ENOENT); |
593 | 0 | } |
594 | 1 | if (rc) |
595 | 0 | log_fatal("can't init trustdb: %s\n", gpg_strerror (rc) ); |
596 | 1 | } |
597 | 0 | else |
598 | 0 | BUG(); |
599 | | |
600 | 1 | if(opt.trust_model==TM_AUTO) |
601 | 0 | { |
602 | | /* Try and set the trust model off of whatever the trustdb says |
603 | | it is. */ |
604 | 0 | opt.trust_model=tdbio_read_model(); |
605 | | |
606 | | /* Sanity check this ;) */ |
607 | 0 | if(opt.trust_model != TM_CLASSIC |
608 | 0 | && opt.trust_model != TM_PGP |
609 | 0 | && opt.trust_model != TM_TOFU_PGP |
610 | 0 | && opt.trust_model != TM_TOFU |
611 | 0 | && opt.trust_model != TM_EXTERNAL) |
612 | 0 | { |
613 | 0 | log_info(_("unable to use unknown trust model (%d) - " |
614 | 0 | "assuming %s trust model\n"),opt.trust_model,"pgp"); |
615 | 0 | opt.trust_model = TM_PGP; |
616 | 0 | } |
617 | |
|
618 | 0 | if(opt.verbose) |
619 | 0 | log_info(_("using %s trust model\n"), |
620 | 0 | trust_model_string (opt.trust_model)); |
621 | 0 | } |
622 | | |
623 | 1 | if (opt.trust_model==TM_PGP || opt.trust_model==TM_CLASSIC |
624 | 1 | || opt.trust_model == TM_TOFU || opt.trust_model == TM_TOFU_PGP) |
625 | 1 | { |
626 | | /* Verify the list of ultimately trusted keys and move the |
627 | | --trusted-keys list there as well. */ |
628 | 1 | if(level==1) |
629 | 1 | verify_own_keys (ctrl); |
630 | | |
631 | 1 | if(!tdbio_db_matches_options()) |
632 | 0 | pending_check_trustdb=1; |
633 | 1 | } |
634 | | |
635 | 1 | return 0; |
636 | 1 | } |
637 | | |
638 | | |
639 | | /* Check whether we have a trust database, initializing it if |
640 | | necessary if the trust model is not 'always trust'. Returns true |
641 | | if we do have a usable trust database. */ |
642 | | int |
643 | | have_trustdb (ctrl_t ctrl) |
644 | 0 | { |
645 | 0 | return !init_trustdb (ctrl, opt.trust_model == TM_ALWAYS); |
646 | 0 | } |
647 | | |
648 | | |
649 | | /**************** |
650 | | * Recreate the WoT but do not ask for new ownertrusts. Special |
651 | | * feature: In batch mode and without a forced yes, this is only done |
652 | | * when a check is due. This can be used to run the check from a crontab |
653 | | */ |
654 | | void |
655 | | check_trustdb (ctrl_t ctrl) |
656 | 2 | { |
657 | 2 | init_trustdb (ctrl, 0); |
658 | 2 | if (opt.trust_model == TM_PGP || opt.trust_model == TM_CLASSIC |
659 | 2 | || opt.trust_model == TM_TOFU_PGP || opt.trust_model == TM_TOFU) |
660 | 2 | { |
661 | 2 | if (opt.batch && !opt.answer_yes) |
662 | 0 | { |
663 | 0 | ulong scheduled; |
664 | |
|
665 | 0 | scheduled = tdbio_read_nextcheck (); |
666 | 0 | if (!scheduled) |
667 | 0 | { |
668 | 0 | log_info (_("no need for a trustdb check\n")); |
669 | 0 | return; |
670 | 0 | } |
671 | | |
672 | 0 | if (scheduled > make_timestamp ()) |
673 | 0 | { |
674 | 0 | log_info (_("next trustdb check due at %s\n"), |
675 | 0 | strtimestamp (scheduled)); |
676 | 0 | return; |
677 | 0 | } |
678 | 0 | } |
679 | | |
680 | 2 | validate_keys (ctrl, 0); |
681 | 2 | } |
682 | 0 | else |
683 | 0 | log_info (_("no need for a trustdb check with '%s' trust model\n"), |
684 | 0 | trust_model_string(opt.trust_model)); |
685 | 2 | } |
686 | | |
687 | | |
688 | | /* |
689 | | * Recreate the WoT. |
690 | | */ |
691 | | void |
692 | | update_trustdb (ctrl_t ctrl) |
693 | 0 | { |
694 | 0 | init_trustdb (ctrl, 0); |
695 | 0 | if (opt.trust_model == TM_PGP || opt.trust_model == TM_CLASSIC |
696 | 0 | || opt.trust_model == TM_TOFU_PGP || opt.trust_model == TM_TOFU) |
697 | 0 | validate_keys (ctrl, 1); |
698 | 0 | else |
699 | 0 | log_info (_("no need for a trustdb update with '%s' trust model\n"), |
700 | 0 | trust_model_string(opt.trust_model)); |
701 | 0 | } |
702 | | |
703 | | void |
704 | | tdb_revalidation_mark (ctrl_t ctrl) |
705 | 11 | { |
706 | 11 | init_trustdb (ctrl, 0); |
707 | 11 | if (trustdb_args.no_trustdb && opt.trust_model == TM_ALWAYS) |
708 | 0 | return; |
709 | | |
710 | | /* We simply set the time for the next check to 1 (far back in 1970) |
711 | | so that a --update-trustdb will be scheduled. */ |
712 | 11 | if (tdbio_write_nextcheck (ctrl, 1)) |
713 | 2 | do_sync (); |
714 | 11 | pending_check_trustdb = 1; |
715 | 11 | } |
716 | | |
717 | | int |
718 | | trustdb_pending_check(void) |
719 | 53 | { |
720 | 53 | return pending_check_trustdb; |
721 | 53 | } |
722 | | |
723 | | /* If the trustdb is dirty, and we're interactive, update it. |
724 | | Otherwise, check it unless no-auto-check-trustdb is set. */ |
725 | | void |
726 | | tdb_check_or_update (ctrl_t ctrl) |
727 | 53 | { |
728 | 53 | if (trustdb_pending_check ()) |
729 | 2 | { |
730 | 2 | if (opt.interactive) |
731 | 0 | update_trustdb (ctrl); |
732 | 2 | else if (!opt.no_auto_check_trustdb) |
733 | 2 | check_trustdb (ctrl); |
734 | 2 | } |
735 | 53 | } |
736 | | |
737 | | void |
738 | | read_trust_options (ctrl_t ctrl, |
739 | | byte *trust_model, ulong *created, ulong *nextcheck, |
740 | | byte *marginals, byte *completes, byte *cert_depth, |
741 | | byte *min_cert_level) |
742 | 0 | { |
743 | 0 | TRUSTREC opts; |
744 | |
|
745 | 0 | init_trustdb (ctrl, 0); |
746 | 0 | if (trustdb_args.no_trustdb && opt.trust_model == TM_ALWAYS) |
747 | 0 | memset (&opts, 0, sizeof opts); |
748 | 0 | else |
749 | 0 | read_record (0, &opts, RECTYPE_VER); |
750 | |
|
751 | 0 | if(trust_model) |
752 | 0 | *trust_model=opts.r.ver.trust_model; |
753 | 0 | if(created) |
754 | 0 | *created=opts.r.ver.created; |
755 | 0 | if(nextcheck) |
756 | 0 | *nextcheck=opts.r.ver.nextcheck; |
757 | 0 | if(marginals) |
758 | 0 | *marginals=opts.r.ver.marginals; |
759 | 0 | if(completes) |
760 | 0 | *completes=opts.r.ver.completes; |
761 | 0 | if(cert_depth) |
762 | 0 | *cert_depth=opts.r.ver.cert_depth; |
763 | 0 | if(min_cert_level) |
764 | 0 | *min_cert_level=opts.r.ver.min_cert_level; |
765 | 0 | } |
766 | | |
767 | | /*********************************************** |
768 | | *********** Ownertrust et al. **************** |
769 | | ***********************************************/ |
770 | | |
771 | | static int |
772 | | read_trust_record (ctrl_t ctrl, PKT_public_key *pk, TRUSTREC *rec) |
773 | 2 | { |
774 | 2 | int rc; |
775 | | |
776 | 2 | init_trustdb (ctrl, 0); |
777 | 2 | rc = tdbio_search_trust_bypk (ctrl, pk, rec); |
778 | 2 | if (rc) |
779 | 2 | { |
780 | 2 | if (gpg_err_code (rc) != GPG_ERR_NOT_FOUND) |
781 | 0 | log_error ("trustdb: searching trust record failed: %s\n", |
782 | 0 | gpg_strerror (rc)); |
783 | 2 | return rc; |
784 | 2 | } |
785 | | |
786 | 0 | if (rec->rectype != RECTYPE_TRUST) |
787 | 0 | { |
788 | 0 | log_error ("trustdb: record %lu is not a trust record\n", |
789 | 0 | rec->recnum); |
790 | 0 | return GPG_ERR_TRUSTDB; |
791 | 0 | } |
792 | | |
793 | 0 | return 0; |
794 | 0 | } |
795 | | |
796 | | |
797 | | /* |
798 | | * Return the assigned ownertrust value for the given public key. The |
799 | | * key should be the primary key. If NO_CREATE is set a missing |
800 | | * trustdb will not be created. This comes for example handy when we |
801 | | * want to print status lines (DECRYPTION_KEY) which carry ownertrust |
802 | | * values but we usually use --always-trust. |
803 | | */ |
804 | | unsigned int |
805 | | tdb_get_ownertrust (ctrl_t ctrl, PKT_public_key *pk, int no_create) |
806 | 0 | { |
807 | 0 | TRUSTREC rec; |
808 | 0 | gpg_error_t err; |
809 | |
|
810 | 0 | if (trustdb_args.no_trustdb && opt.trust_model == TM_ALWAYS) |
811 | 0 | return TRUST_UNKNOWN; |
812 | | |
813 | | /* If the caller asked not to create a trustdb we call init_trustdb |
814 | | * directly and allow it to fail with an error code for a |
815 | | * non-existing trustdb. */ |
816 | 0 | if (no_create && init_trustdb (ctrl, 1)) |
817 | 0 | return TRUST_UNKNOWN; |
818 | | |
819 | 0 | err = read_trust_record (ctrl, pk, &rec); |
820 | 0 | if (gpg_err_code (err) == GPG_ERR_NOT_FOUND) |
821 | 0 | return TRUST_UNKNOWN; /* no record yet */ |
822 | 0 | if (err) |
823 | 0 | { |
824 | 0 | tdbio_invalid (); |
825 | 0 | return TRUST_UNKNOWN; /* actually never reached */ |
826 | 0 | } |
827 | | |
828 | 0 | return rec.r.trust.ownertrust; |
829 | 0 | } |
830 | | |
831 | | |
832 | | unsigned int |
833 | | tdb_get_min_ownertrust (ctrl_t ctrl, PKT_public_key *pk, int no_create) |
834 | 0 | { |
835 | 0 | TRUSTREC rec; |
836 | 0 | gpg_error_t err; |
837 | |
|
838 | 0 | if (trustdb_args.no_trustdb && opt.trust_model == TM_ALWAYS) |
839 | 0 | return TRUST_UNKNOWN; |
840 | | |
841 | | /* If the caller asked not to create a trustdb we call init_trustdb |
842 | | * directly and allow it to fail with an error code for a |
843 | | * non-existing trustdb. */ |
844 | 0 | if (no_create && init_trustdb (ctrl, 1)) |
845 | 0 | return TRUST_UNKNOWN; |
846 | | |
847 | 0 | err = read_trust_record (ctrl, pk, &rec); |
848 | 0 | if (gpg_err_code (err) == GPG_ERR_NOT_FOUND) |
849 | 0 | return TRUST_UNKNOWN; /* no record yet */ |
850 | 0 | if (err) |
851 | 0 | { |
852 | 0 | tdbio_invalid (); |
853 | 0 | return TRUST_UNKNOWN; /* actually never reached */ |
854 | 0 | } |
855 | | |
856 | 0 | return rec.r.trust.min_ownertrust; |
857 | 0 | } |
858 | | |
859 | | |
860 | | /* |
861 | | * Set the trust value of the given public key to the new value. |
862 | | * The key should be a primary one. |
863 | | */ |
864 | | void |
865 | | tdb_update_ownertrust (ctrl_t ctrl, PKT_public_key *pk, unsigned int new_trust, |
866 | | int as_trusted_key) |
867 | 0 | { |
868 | 0 | TRUSTREC rec; |
869 | 0 | gpg_error_t err; |
870 | |
|
871 | 0 | if (trustdb_args.no_trustdb && opt.trust_model == TM_ALWAYS) |
872 | 0 | return; |
873 | | |
874 | 0 | err = read_trust_record (ctrl, pk, &rec); |
875 | 0 | if (!err) |
876 | 0 | { |
877 | 0 | if (DBG_TRUST) |
878 | 0 | log_debug ("update ownertrust from %u to %u%s\n", |
879 | 0 | (unsigned int)rec.r.trust.ownertrust, new_trust, |
880 | 0 | as_trusted_key? " via --trusted-key":""); |
881 | 0 | if (rec.r.trust.ownertrust != new_trust) |
882 | 0 | { |
883 | 0 | rec.r.trust.ownertrust = new_trust; |
884 | | /* Clear or set the trusted key flag if the new value is |
885 | | * ultimate. This is required so that we know which keys |
886 | | * have been added by --trusted-keys. */ |
887 | 0 | if ((rec.r.trust.ownertrust & TRUST_MASK) == TRUST_ULTIMATE) |
888 | 0 | { |
889 | 0 | if (as_trusted_key) |
890 | 0 | rec.r.trust.flags |= 1; |
891 | 0 | else |
892 | 0 | rec.r.trust.flags &= ~(rec.r.trust.flags & 1); |
893 | 0 | } |
894 | 0 | else |
895 | 0 | rec.r.trust.flags &= ~(rec.r.trust.flags & 1); |
896 | 0 | write_record (ctrl, &rec); |
897 | 0 | tdb_revalidation_mark (ctrl); |
898 | 0 | do_sync (); |
899 | 0 | } |
900 | 0 | } |
901 | 0 | else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND) |
902 | 0 | { /* no record yet - create a new one */ |
903 | 0 | if (DBG_TRUST) |
904 | 0 | log_debug ("insert ownertrust %u%s\n", new_trust, |
905 | 0 | as_trusted_key? " via --trusted-key":""); |
906 | |
|
907 | 0 | memset (&rec, 0, sizeof rec); |
908 | 0 | rec.recnum = tdbio_new_recnum (ctrl); |
909 | 0 | rec.rectype = RECTYPE_TRUST; |
910 | 0 | fpr20_from_pk (pk, rec.r.trust.fingerprint); |
911 | 0 | rec.r.trust.ownertrust = new_trust; |
912 | 0 | if ((rec.r.trust.ownertrust & TRUST_MASK) == TRUST_ULTIMATE |
913 | 0 | && as_trusted_key) |
914 | 0 | rec.r.trust.flags = 1; |
915 | 0 | write_record (ctrl, &rec); |
916 | 0 | tdb_revalidation_mark (ctrl); |
917 | 0 | do_sync (); |
918 | 0 | } |
919 | 0 | else |
920 | 0 | { |
921 | 0 | tdbio_invalid (); |
922 | 0 | } |
923 | 0 | } |
924 | | |
925 | | static void |
926 | | update_min_ownertrust (ctrl_t ctrl, u32 *kid, unsigned int new_trust) |
927 | 0 | { |
928 | 0 | PKT_public_key *pk; |
929 | 0 | TRUSTREC rec; |
930 | 0 | gpg_error_t err; |
931 | |
|
932 | 0 | if (trustdb_args.no_trustdb && opt.trust_model == TM_ALWAYS) |
933 | 0 | return; |
934 | | |
935 | 0 | pk = xmalloc_clear (sizeof *pk); |
936 | 0 | err = get_pubkey (ctrl, pk, kid); |
937 | 0 | if (err) |
938 | 0 | { |
939 | 0 | log_error (_("public key %s not found: %s\n"), |
940 | 0 | keystr (kid), gpg_strerror (err)); |
941 | 0 | xfree (pk); |
942 | 0 | return; |
943 | 0 | } |
944 | | |
945 | 0 | err = read_trust_record (ctrl, pk, &rec); |
946 | 0 | if (!err) |
947 | 0 | { |
948 | 0 | if (DBG_TRUST) |
949 | 0 | log_debug ("key %08lX%08lX: update min_ownertrust from %u to %u\n", |
950 | 0 | (ulong)kid[0],(ulong)kid[1], |
951 | 0 | (unsigned int)rec.r.trust.min_ownertrust, |
952 | 0 | new_trust ); |
953 | 0 | if (rec.r.trust.min_ownertrust != new_trust) |
954 | 0 | { |
955 | 0 | rec.r.trust.min_ownertrust = new_trust; |
956 | 0 | write_record (ctrl, &rec); |
957 | 0 | tdb_revalidation_mark (ctrl); |
958 | 0 | do_sync (); |
959 | 0 | } |
960 | 0 | } |
961 | 0 | else if (gpg_err_code (err) == GPG_ERR_NOT_FOUND) |
962 | 0 | { /* no record yet - create a new one */ |
963 | 0 | if (DBG_TRUST) |
964 | 0 | log_debug ("insert min_ownertrust %u\n", new_trust ); |
965 | |
|
966 | 0 | memset (&rec, 0, sizeof rec); |
967 | 0 | rec.recnum = tdbio_new_recnum (ctrl); |
968 | 0 | rec.rectype = RECTYPE_TRUST; |
969 | 0 | fpr20_from_pk (pk, rec.r.trust.fingerprint); |
970 | 0 | rec.r.trust.min_ownertrust = new_trust; |
971 | 0 | write_record (ctrl, &rec); |
972 | 0 | tdb_revalidation_mark (ctrl); |
973 | 0 | do_sync (); |
974 | 0 | } |
975 | 0 | else |
976 | 0 | { |
977 | 0 | tdbio_invalid (); |
978 | 0 | } |
979 | |
|
980 | 0 | free_public_key (pk); |
981 | 0 | } |
982 | | |
983 | | |
984 | | /* |
985 | | * Clear the ownertrust and min_ownertrust values. |
986 | | * |
987 | | * Return: True if a change actually happened. |
988 | | */ |
989 | | int |
990 | | tdb_clear_ownertrusts (ctrl_t ctrl, PKT_public_key *pk) |
991 | 2 | { |
992 | 2 | TRUSTREC rec; |
993 | 2 | gpg_error_t err; |
994 | | |
995 | 2 | init_trustdb (ctrl, 0); |
996 | | |
997 | 2 | if (trustdb_args.no_trustdb && opt.trust_model == TM_ALWAYS) |
998 | 0 | return 0; |
999 | | |
1000 | 2 | err = read_trust_record (ctrl, pk, &rec); |
1001 | 2 | if (!err) |
1002 | 0 | { |
1003 | 0 | if (DBG_TRUST) |
1004 | 0 | { |
1005 | 0 | log_debug ("clearing ownertrust (old value %u)\n", |
1006 | 0 | (unsigned int)rec.r.trust.ownertrust); |
1007 | 0 | log_debug ("clearing min_ownertrust (old value %u)\n", |
1008 | 0 | (unsigned int)rec.r.trust.min_ownertrust); |
1009 | 0 | } |
1010 | 0 | if (rec.r.trust.ownertrust || rec.r.trust.min_ownertrust) |
1011 | 0 | { |
1012 | 0 | rec.r.trust.ownertrust = 0; |
1013 | 0 | rec.r.trust.min_ownertrust = 0; |
1014 | 0 | write_record (ctrl, &rec); |
1015 | 0 | tdb_revalidation_mark (ctrl); |
1016 | 0 | do_sync (); |
1017 | 0 | return 1; |
1018 | 0 | } |
1019 | 0 | } |
1020 | 2 | else if (gpg_err_code (err) != GPG_ERR_NOT_FOUND) |
1021 | 0 | { |
1022 | 0 | tdbio_invalid (); |
1023 | 0 | } |
1024 | 2 | return 0; |
1025 | 2 | } |
1026 | | |
1027 | | /* |
1028 | | * Note: Caller has to do a sync |
1029 | | */ |
1030 | | static void |
1031 | | update_validity (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *uid, |
1032 | | int depth, int validity) |
1033 | 0 | { |
1034 | 0 | TRUSTREC trec, vrec; |
1035 | 0 | gpg_error_t err; |
1036 | 0 | ulong recno; |
1037 | |
|
1038 | 0 | namehash_from_uid(uid); |
1039 | |
|
1040 | 0 | err = read_trust_record (ctrl, pk, &trec); |
1041 | 0 | if (err && gpg_err_code (err) != GPG_ERR_NOT_FOUND) |
1042 | 0 | { |
1043 | 0 | tdbio_invalid (); |
1044 | 0 | return; |
1045 | 0 | } |
1046 | 0 | if (gpg_err_code (err) == GPG_ERR_NOT_FOUND) |
1047 | 0 | { |
1048 | | /* No record yet - create a new one. */ |
1049 | 0 | memset (&trec, 0, sizeof trec); |
1050 | 0 | trec.recnum = tdbio_new_recnum (ctrl); |
1051 | 0 | trec.rectype = RECTYPE_TRUST; |
1052 | 0 | fpr20_from_pk (pk, trec.r.trust.fingerprint); |
1053 | 0 | trec.r.trust.ownertrust = 0; |
1054 | 0 | } |
1055 | | |
1056 | | /* locate an existing one */ |
1057 | 0 | recno = trec.r.trust.validlist; |
1058 | 0 | while (recno) |
1059 | 0 | { |
1060 | 0 | read_record (recno, &vrec, RECTYPE_VALID); |
1061 | 0 | if ( !memcmp (vrec.r.valid.namehash, uid->namehash, 20) ) |
1062 | 0 | break; |
1063 | 0 | recno = vrec.r.valid.next; |
1064 | 0 | } |
1065 | |
|
1066 | 0 | if (!recno) /* insert a new validity record */ |
1067 | 0 | { |
1068 | 0 | memset (&vrec, 0, sizeof vrec); |
1069 | 0 | vrec.recnum = tdbio_new_recnum (ctrl); |
1070 | 0 | vrec.rectype = RECTYPE_VALID; |
1071 | 0 | memcpy (vrec.r.valid.namehash, uid->namehash, 20); |
1072 | 0 | vrec.r.valid.next = trec.r.trust.validlist; |
1073 | 0 | trec.r.trust.validlist = vrec.recnum; |
1074 | 0 | } |
1075 | 0 | vrec.r.valid.validity = validity; |
1076 | 0 | vrec.r.valid.full_count = uid->help_full_count; |
1077 | 0 | vrec.r.valid.marginal_count = uid->help_marginal_count; |
1078 | 0 | write_record (ctrl, &vrec); |
1079 | 0 | trec.r.trust.depth = depth; |
1080 | 0 | write_record (ctrl, &trec); |
1081 | 0 | } |
1082 | | |
1083 | | |
1084 | | /*********************************************** |
1085 | | ********* Query trustdb values ************** |
1086 | | ***********************************************/ |
1087 | | |
1088 | | /* Return true if key is disabled. Note that this is usually used via |
1089 | | the pk_is_disabled macro. */ |
1090 | | int |
1091 | | tdb_cache_disabled_value (ctrl_t ctrl, PKT_public_key *pk) |
1092 | 0 | { |
1093 | 0 | gpg_error_t err; |
1094 | 0 | TRUSTREC trec; |
1095 | 0 | int disabled = 0; |
1096 | |
|
1097 | 0 | if (pk->flags.disabled_valid) |
1098 | 0 | return pk->flags.disabled; |
1099 | | |
1100 | 0 | init_trustdb (ctrl, 0); |
1101 | |
|
1102 | 0 | if (trustdb_args.no_trustdb) |
1103 | 0 | return 0; /* No trustdb => not disabled. */ |
1104 | | |
1105 | 0 | err = read_trust_record (ctrl, pk, &trec); |
1106 | 0 | if (err && gpg_err_code (err) != GPG_ERR_NOT_FOUND) |
1107 | 0 | { |
1108 | 0 | tdbio_invalid (); |
1109 | 0 | goto leave; |
1110 | 0 | } |
1111 | 0 | if (gpg_err_code (err) == GPG_ERR_NOT_FOUND) |
1112 | 0 | { |
1113 | | /* No record found, so assume not disabled. */ |
1114 | 0 | goto leave; |
1115 | 0 | } |
1116 | | |
1117 | 0 | if ((trec.r.trust.ownertrust & TRUST_FLAG_DISABLED)) |
1118 | 0 | disabled = 1; |
1119 | | |
1120 | | /* Cache it for later so we don't need to look at the trustdb every |
1121 | | time */ |
1122 | 0 | pk->flags.disabled = disabled; |
1123 | 0 | pk->flags.disabled_valid = 1; |
1124 | |
|
1125 | 0 | leave: |
1126 | 0 | return disabled; |
1127 | 0 | } |
1128 | | |
1129 | | |
1130 | | void |
1131 | | tdb_check_trustdb_stale (ctrl_t ctrl) |
1132 | 1 | { |
1133 | 1 | static int did_nextcheck=0; |
1134 | | |
1135 | 1 | init_trustdb (ctrl, 0); |
1136 | | |
1137 | 1 | if (trustdb_args.no_trustdb) |
1138 | 0 | return; /* No trustdb => can't be stale. */ |
1139 | | |
1140 | 1 | if (!did_nextcheck |
1141 | 1 | && (opt.trust_model == TM_PGP || opt.trust_model == TM_CLASSIC |
1142 | 1 | || opt.trust_model == TM_TOFU_PGP || opt.trust_model == TM_TOFU)) |
1143 | 1 | { |
1144 | 1 | ulong scheduled; |
1145 | | |
1146 | 1 | did_nextcheck = 1; |
1147 | 1 | scheduled = tdbio_read_nextcheck (); |
1148 | 1 | if ((scheduled && scheduled <= make_timestamp ()) |
1149 | 1 | || pending_check_trustdb) |
1150 | 0 | { |
1151 | 0 | if (opt.no_auto_check_trustdb) |
1152 | 0 | { |
1153 | 0 | pending_check_trustdb = 1; |
1154 | 0 | if (!opt.quiet) |
1155 | 0 | log_info (_("please do a --check-trustdb\n")); |
1156 | 0 | } |
1157 | 0 | else |
1158 | 0 | { |
1159 | 0 | if (!opt.quiet) |
1160 | 0 | log_info (_("checking the trustdb\n")); |
1161 | 0 | validate_keys (ctrl, 0); |
1162 | 0 | } |
1163 | 0 | } |
1164 | 1 | } |
1165 | 1 | } |
1166 | | |
1167 | | /* |
1168 | | * Return the validity information for KB/PK (at least one of them |
1169 | | * must be non-NULL). This is the core of get_validity. If SIG is |
1170 | | * not NULL, then the trust is being evaluated in the context of the |
1171 | | * provided signature. This is used by the TOFU code to record |
1172 | | * statistics. |
1173 | | */ |
1174 | | unsigned int |
1175 | | tdb_get_validity_core (ctrl_t ctrl, |
1176 | | kbnode_t kb, |
1177 | | PKT_public_key *pk, PKT_user_id *uid, |
1178 | | PKT_public_key *main_pk, |
1179 | | PKT_signature *sig, |
1180 | | int may_ask) |
1181 | 0 | { |
1182 | 0 | TRUSTREC trec, vrec; |
1183 | 0 | gpg_error_t err = 0; |
1184 | 0 | ulong recno; |
1185 | | #ifdef USE_TOFU |
1186 | | unsigned int tofu_validity = TRUST_UNKNOWN; |
1187 | | int free_kb = 0; |
1188 | | #endif |
1189 | 0 | unsigned int validity = TRUST_UNKNOWN; |
1190 | |
|
1191 | 0 | if (kb && pk) |
1192 | 0 | log_assert (keyid_cmp (pk_main_keyid (pk), |
1193 | 0 | pk_main_keyid (kb->pkt->pkt.public_key)) == 0); |
1194 | | |
1195 | 0 | if (! pk) |
1196 | 0 | { |
1197 | 0 | log_assert (kb); |
1198 | 0 | pk = kb->pkt->pkt.public_key; |
1199 | 0 | } |
1200 | | |
1201 | 0 | #ifndef USE_TOFU |
1202 | 0 | (void)sig; |
1203 | 0 | (void)may_ask; |
1204 | 0 | #endif |
1205 | |
|
1206 | 0 | init_trustdb (ctrl, 0); |
1207 | | |
1208 | | /* If we have no trustdb (which also means it has not been created) |
1209 | | and the trust-model is always, we don't know the validity - |
1210 | | return immediately. If we won't do that the tdbio code would try |
1211 | | to open the trustdb and run into a fatal error. */ |
1212 | 0 | if (trustdb_args.no_trustdb && opt.trust_model == TM_ALWAYS) |
1213 | 0 | return TRUST_UNKNOWN; |
1214 | | |
1215 | 0 | check_trustdb_stale (ctrl); |
1216 | |
|
1217 | 0 | if(opt.trust_model==TM_DIRECT) |
1218 | 0 | { |
1219 | | /* Note that this happens BEFORE any user ID stuff is checked. |
1220 | | The direct trust model applies to keys as a whole. */ |
1221 | 0 | validity = tdb_get_ownertrust (ctrl, main_pk, 0); |
1222 | 0 | goto leave; |
1223 | 0 | } |
1224 | | |
1225 | | #ifdef USE_TOFU |
1226 | | if (opt.trust_model == TM_TOFU || opt.trust_model == TM_TOFU_PGP) |
1227 | | { |
1228 | | kbnode_t n = NULL; |
1229 | | strlist_t user_id_list = NULL; |
1230 | | int done = 0; |
1231 | | |
1232 | | /* If the caller didn't supply a user id then use all uids. */ |
1233 | | if (! uid) |
1234 | | { |
1235 | | if (! kb) |
1236 | | { |
1237 | | kb = get_pubkeyblock (ctrl, main_pk->keyid); |
1238 | | free_kb = 1; |
1239 | | } |
1240 | | n = kb; |
1241 | | } |
1242 | | |
1243 | | if (DBG_TRUST && sig && sig->signers_uid) |
1244 | | log_debug ("TOFU: only considering user id: '%s'\n", |
1245 | | sig->signers_uid); |
1246 | | |
1247 | | while (!done && (uid || (n = find_next_kbnode (n, PKT_USER_ID)))) |
1248 | | { |
1249 | | PKT_user_id *user_id; |
1250 | | int expired = 0; |
1251 | | |
1252 | | if (uid) |
1253 | | { |
1254 | | user_id = uid; |
1255 | | /* If the caller specified a user id, then we only |
1256 | | process the specified user id and are done after the |
1257 | | first iteration. */ |
1258 | | done = 1; |
1259 | | } |
1260 | | else |
1261 | | user_id = n->pkt->pkt.user_id; |
1262 | | |
1263 | | if (user_id->attrib_data) |
1264 | | /* Skip user attributes. */ |
1265 | | continue; |
1266 | | |
1267 | | if (sig && sig->signers_uid) |
1268 | | /* Make sure the UID matches. */ |
1269 | | { |
1270 | | char *email = mailbox_from_userid (user_id->name, 0); |
1271 | | if (!email || !*email || strcmp (sig->signers_uid, email) != 0) |
1272 | | { |
1273 | | if (DBG_TRUST) |
1274 | | log_debug ("TOFU: skipping user id '%s', which does" |
1275 | | " not match the signer's email ('%s')\n", |
1276 | | email, sig->signers_uid); |
1277 | | xfree (email); |
1278 | | continue; |
1279 | | } |
1280 | | xfree (email); |
1281 | | } |
1282 | | |
1283 | | /* If the user id is revoked or expired, then skip it. */ |
1284 | | if (user_id->flags.revoked || user_id->flags.expired) |
1285 | | { |
1286 | | if (DBG_TRUST) |
1287 | | { |
1288 | | char *s; |
1289 | | if (user_id->flags.revoked && user_id->flags.expired) |
1290 | | s = "revoked and expired"; |
1291 | | else if (user_id->flags.revoked) |
1292 | | s = "revoked"; |
1293 | | else |
1294 | | s = "expire"; |
1295 | | |
1296 | | log_debug ("TOFU: Ignoring %s user id (%s)\n", |
1297 | | s, user_id->name); |
1298 | | } |
1299 | | |
1300 | | if (user_id->flags.revoked) |
1301 | | continue; |
1302 | | |
1303 | | expired = 1; |
1304 | | } |
1305 | | |
1306 | | add_to_strlist (&user_id_list, user_id->name); |
1307 | | user_id_list->flags = expired; |
1308 | | } |
1309 | | |
1310 | | /* Process the user ids in the order they appear in the key |
1311 | | block. */ |
1312 | | strlist_rev (&user_id_list); |
1313 | | |
1314 | | /* It only makes sense to observe any signature before getting |
1315 | | the validity. This is because if the current signature |
1316 | | results in a conflict, then we damn well want to take that |
1317 | | into account. */ |
1318 | | if (sig) |
1319 | | { |
1320 | | err = tofu_register_signature (ctrl, main_pk, user_id_list, |
1321 | | sig->digest, sig->digest_len, |
1322 | | sig->timestamp, "unknown"); |
1323 | | if (err) |
1324 | | { |
1325 | | log_error ("TOFU: error registering signature: %s\n", |
1326 | | gpg_strerror (err)); |
1327 | | |
1328 | | tofu_validity = TRUST_UNKNOWN; |
1329 | | } |
1330 | | } |
1331 | | if (! err) |
1332 | | tofu_validity = tofu_get_validity (ctrl, main_pk, user_id_list, |
1333 | | may_ask); |
1334 | | |
1335 | | free_strlist (user_id_list); |
1336 | | if (free_kb) |
1337 | | release_kbnode (kb); |
1338 | | } |
1339 | | #endif /*USE_TOFU*/ |
1340 | | |
1341 | 0 | if (opt.trust_model == TM_TOFU_PGP |
1342 | 0 | || opt.trust_model == TM_CLASSIC |
1343 | 0 | || opt.trust_model == TM_PGP) |
1344 | 0 | { |
1345 | 0 | err = read_trust_record (ctrl, main_pk, &trec); |
1346 | 0 | if (err && gpg_err_code (err) != GPG_ERR_NOT_FOUND) |
1347 | 0 | { |
1348 | 0 | tdbio_invalid (); |
1349 | 0 | return 0; |
1350 | 0 | } |
1351 | 0 | if (gpg_err_code (err) == GPG_ERR_NOT_FOUND) |
1352 | 0 | { |
1353 | | /* No record found. */ |
1354 | 0 | validity = TRUST_UNKNOWN; |
1355 | 0 | goto leave; |
1356 | 0 | } |
1357 | | |
1358 | | /* Loop over all user IDs */ |
1359 | 0 | recno = trec.r.trust.validlist; |
1360 | 0 | validity = 0; |
1361 | 0 | while (recno) |
1362 | 0 | { |
1363 | 0 | read_record (recno, &vrec, RECTYPE_VALID); |
1364 | |
|
1365 | 0 | if(uid) |
1366 | 0 | { |
1367 | | /* If a user ID is given we return the validity for that |
1368 | | user ID ONLY. If the namehash is not found, then |
1369 | | there is no validity at all (i.e. the user ID wasn't |
1370 | | signed). */ |
1371 | 0 | if(memcmp(vrec.r.valid.namehash,uid->namehash,20)==0) |
1372 | 0 | { |
1373 | 0 | validity=(vrec.r.valid.validity & TRUST_MASK); |
1374 | 0 | break; |
1375 | 0 | } |
1376 | 0 | } |
1377 | 0 | else |
1378 | 0 | { |
1379 | | /* If no user ID is given, we take the maximum validity |
1380 | | over all user IDs */ |
1381 | 0 | if (validity < (vrec.r.valid.validity & TRUST_MASK)) |
1382 | 0 | validity = (vrec.r.valid.validity & TRUST_MASK); |
1383 | 0 | } |
1384 | | |
1385 | 0 | recno = vrec.r.valid.next; |
1386 | 0 | } |
1387 | |
|
1388 | 0 | if ((trec.r.trust.ownertrust & TRUST_FLAG_DISABLED)) |
1389 | 0 | { |
1390 | 0 | validity |= TRUST_FLAG_DISABLED; |
1391 | 0 | pk->flags.disabled = 1; |
1392 | 0 | } |
1393 | 0 | else |
1394 | 0 | pk->flags.disabled = 0; |
1395 | 0 | pk->flags.disabled_valid = 1; |
1396 | 0 | } |
1397 | | |
1398 | 0 | leave: |
1399 | | #ifdef USE_TOFU |
1400 | | validity = tofu_wot_trust_combine (tofu_validity, validity); |
1401 | | #else /*!USE_TOFU*/ |
1402 | 0 | validity &= TRUST_MASK; |
1403 | |
|
1404 | 0 | if (validity == TRUST_NEVER) |
1405 | | /* TRUST_NEVER trumps everything else. */ |
1406 | 0 | validity |= TRUST_NEVER; |
1407 | 0 | if (validity == TRUST_EXPIRED) |
1408 | | /* TRUST_EXPIRED trumps everything but TRUST_NEVER. */ |
1409 | 0 | validity |= TRUST_EXPIRED; |
1410 | 0 | #endif /*!USE_TOFU*/ |
1411 | |
|
1412 | 0 | if (opt.trust_model != TM_TOFU |
1413 | 0 | && pending_check_trustdb) |
1414 | 0 | validity |= TRUST_FLAG_PENDING_CHECK; |
1415 | |
|
1416 | 0 | return validity; |
1417 | 0 | } |
1418 | | |
1419 | | |
1420 | | static void |
1421 | | get_validity_counts (ctrl_t ctrl, PKT_public_key *pk, PKT_user_id *uid) |
1422 | 0 | { |
1423 | 0 | TRUSTREC trec, vrec; |
1424 | 0 | ulong recno; |
1425 | |
|
1426 | 0 | if(pk==NULL || uid==NULL) |
1427 | 0 | BUG(); |
1428 | | |
1429 | 0 | namehash_from_uid(uid); |
1430 | |
|
1431 | 0 | uid->help_marginal_count=uid->help_full_count=0; |
1432 | |
|
1433 | 0 | init_trustdb (ctrl, 0); |
1434 | |
|
1435 | 0 | if(read_trust_record (ctrl, pk, &trec)) |
1436 | 0 | return; |
1437 | | |
1438 | | /* loop over all user IDs */ |
1439 | 0 | recno = trec.r.trust.validlist; |
1440 | 0 | while (recno) |
1441 | 0 | { |
1442 | 0 | read_record (recno, &vrec, RECTYPE_VALID); |
1443 | |
|
1444 | 0 | if(memcmp(vrec.r.valid.namehash,uid->namehash,20)==0) |
1445 | 0 | { |
1446 | 0 | uid->help_marginal_count=vrec.r.valid.marginal_count; |
1447 | 0 | uid->help_full_count=vrec.r.valid.full_count; |
1448 | | /* es_printf("Fetched marginal %d, full %d\n",uid->help_marginal_count,uid->help_full_count); */ |
1449 | 0 | break; |
1450 | 0 | } |
1451 | | |
1452 | 0 | recno = vrec.r.valid.next; |
1453 | 0 | } |
1454 | 0 | } |
1455 | | |
1456 | | void |
1457 | | list_trust_path( const char *username ) |
1458 | 0 | { |
1459 | 0 | (void)username; |
1460 | 0 | } |
1461 | | |
1462 | | /**************** |
1463 | | * Enumerate all keys, which are needed to build all trust paths for |
1464 | | * the given key. This function does not return the key itself or |
1465 | | * the ultimate key (the last point in cerificate chain). Only |
1466 | | * certificate chains which ends up at an ultimately trusted key |
1467 | | * are listed. If ownertrust or validity is not NULL, the corresponding |
1468 | | * value for the returned LID is also returned in these variable(s). |
1469 | | * |
1470 | | * 1) create a void pointer and initialize it to NULL |
1471 | | * 2) pass this void pointer by reference to this function. |
1472 | | * Set lid to the key you want to enumerate and pass it by reference. |
1473 | | * 3) call this function as long as it does not return -1 |
1474 | | * to indicate EOF. LID does contain the next key used to build the web |
1475 | | * 4) Always call this function a last time with LID set to NULL, |
1476 | | * so that it can free its context. |
1477 | | * |
1478 | | * Returns: -1 on EOF or the level of the returned LID |
1479 | | */ |
1480 | | int |
1481 | | enum_cert_paths( void **context, ulong *lid, |
1482 | | unsigned *ownertrust, unsigned *validity ) |
1483 | 0 | { |
1484 | 0 | (void)context; |
1485 | 0 | (void)lid; |
1486 | 0 | (void)ownertrust; |
1487 | 0 | (void)validity; |
1488 | 0 | return -1; |
1489 | 0 | } |
1490 | | |
1491 | | |
1492 | | /**************** |
1493 | | * Print the current path |
1494 | | */ |
1495 | | void |
1496 | | enum_cert_paths_print (void **context, FILE *fp, |
1497 | | int refresh, ulong selected_lid) |
1498 | 0 | { |
1499 | 0 | (void)context; |
1500 | 0 | (void)fp; |
1501 | 0 | (void)refresh; |
1502 | 0 | (void)selected_lid; |
1503 | 0 | } |
1504 | | |
1505 | | |
1506 | | |
1507 | | /**************************************** |
1508 | | *********** NEW NEW NEW **************** |
1509 | | ****************************************/ |
1510 | | |
1511 | | static int |
1512 | | ask_ownertrust (ctrl_t ctrl, u32 *kid, int minimum) |
1513 | 0 | { |
1514 | 0 | PKT_public_key *pk; |
1515 | 0 | int rc; |
1516 | 0 | int ot; |
1517 | |
|
1518 | 0 | pk = xmalloc_clear (sizeof *pk); |
1519 | 0 | rc = get_pubkey (ctrl, pk, kid); |
1520 | 0 | if (rc) |
1521 | 0 | { |
1522 | 0 | log_error (_("public key %s not found: %s\n"), |
1523 | 0 | keystr(kid), gpg_strerror (rc) ); |
1524 | 0 | free_public_key (pk); |
1525 | 0 | return TRUST_UNKNOWN; |
1526 | 0 | } |
1527 | | |
1528 | 0 | if(opt.force_ownertrust) |
1529 | 0 | { |
1530 | 0 | log_info("force trust for key %s to %s\n", |
1531 | 0 | keystr(kid),trust_value_to_string(opt.force_ownertrust)); |
1532 | 0 | tdb_update_ownertrust (ctrl, pk, opt.force_ownertrust, 0); |
1533 | 0 | ot=opt.force_ownertrust; |
1534 | 0 | } |
1535 | 0 | else |
1536 | 0 | { |
1537 | 0 | ot=edit_ownertrust (ctrl, pk, 0); |
1538 | 0 | if(ot>0) |
1539 | 0 | ot = tdb_get_ownertrust (ctrl, pk, 0); |
1540 | 0 | else if(ot==0) |
1541 | 0 | ot = minimum?minimum:TRUST_UNDEFINED; |
1542 | 0 | else |
1543 | 0 | ot = -1; /* quit */ |
1544 | 0 | } |
1545 | |
|
1546 | 0 | free_public_key( pk ); |
1547 | |
|
1548 | 0 | return ot; |
1549 | 0 | } |
1550 | | |
1551 | | |
1552 | | static void |
1553 | | mark_keyblock_seen (KeyHashTable tbl, KBNODE node) |
1554 | 0 | { |
1555 | 0 | for ( ;node; node = node->next ) |
1556 | 0 | if (node->pkt->pkttype == PKT_PUBLIC_KEY |
1557 | 0 | || node->pkt->pkttype == PKT_PUBLIC_SUBKEY) |
1558 | 0 | { |
1559 | 0 | u32 aki[2]; |
1560 | |
|
1561 | 0 | keyid_from_pk (node->pkt->pkt.public_key, aki); |
1562 | 0 | add_key_hash_table (tbl, aki); |
1563 | 0 | } |
1564 | 0 | } |
1565 | | |
1566 | | |
1567 | | static void |
1568 | | dump_key_array (int depth, struct key_array *keys) |
1569 | 0 | { |
1570 | 0 | struct key_array *kar; |
1571 | |
|
1572 | 0 | for (kar=keys; kar->keyblock; kar++) |
1573 | 0 | { |
1574 | 0 | KBNODE node = kar->keyblock; |
1575 | 0 | u32 kid[2]; |
1576 | |
|
1577 | 0 | keyid_from_pk(node->pkt->pkt.public_key, kid); |
1578 | 0 | es_printf ("%d:%08lX%08lX:K::%c::::\n", |
1579 | 0 | depth, (ulong)kid[0], (ulong)kid[1], '?'); |
1580 | |
|
1581 | 0 | for (; node; node = node->next) |
1582 | 0 | { |
1583 | 0 | if (node->pkt->pkttype == PKT_USER_ID) |
1584 | 0 | { |
1585 | 0 | int len = node->pkt->pkt.user_id->len; |
1586 | |
|
1587 | 0 | if (len > 30) |
1588 | 0 | len = 30; |
1589 | 0 | es_printf ("%d:%08lX%08lX:U:::%c:::", |
1590 | 0 | depth, (ulong)kid[0], (ulong)kid[1], |
1591 | 0 | (node->flag & 4)? 'f': |
1592 | 0 | (node->flag & 2)? 'm': |
1593 | 0 | (node->flag & 1)? 'q':'-'); |
1594 | 0 | es_write_sanitized (es_stdout, node->pkt->pkt.user_id->name, |
1595 | 0 | len, ":", NULL); |
1596 | 0 | es_putc (':', es_stdout); |
1597 | 0 | es_putc ('\n', es_stdout); |
1598 | 0 | } |
1599 | 0 | } |
1600 | 0 | } |
1601 | 0 | } |
1602 | | |
1603 | | |
1604 | | static void |
1605 | | store_validation_status (ctrl_t ctrl, int depth, |
1606 | | kbnode_t keyblock, KeyHashTable stored) |
1607 | 0 | { |
1608 | 0 | KBNODE node; |
1609 | 0 | int status; |
1610 | 0 | int any = 0; |
1611 | |
|
1612 | 0 | for (node=keyblock; node; node = node->next) |
1613 | 0 | { |
1614 | 0 | if (node->pkt->pkttype == PKT_USER_ID) |
1615 | 0 | { |
1616 | 0 | PKT_user_id *uid = node->pkt->pkt.user_id; |
1617 | 0 | if (node->flag & 4) |
1618 | 0 | status = TRUST_FULLY; |
1619 | 0 | else if (node->flag & 2) |
1620 | 0 | status = TRUST_MARGINAL; |
1621 | 0 | else if (node->flag & 1) |
1622 | 0 | status = TRUST_UNDEFINED; |
1623 | 0 | else |
1624 | 0 | status = 0; |
1625 | |
|
1626 | 0 | if (status) |
1627 | 0 | { |
1628 | 0 | update_validity (ctrl, keyblock->pkt->pkt.public_key, |
1629 | 0 | uid, depth, status); |
1630 | |
|
1631 | 0 | mark_keyblock_seen(stored,keyblock); |
1632 | |
|
1633 | 0 | any = 1; |
1634 | 0 | } |
1635 | 0 | } |
1636 | 0 | } |
1637 | |
|
1638 | 0 | if (any) |
1639 | 0 | do_sync (); |
1640 | 0 | } |
1641 | | |
1642 | | |
1643 | | /* Returns a sanitized copy of the regexp (which might be "", but not |
1644 | | NULL). */ |
1645 | | /* Operator characters except '.' and backslash. |
1646 | | See regex(7) on BSD. */ |
1647 | 0 | #define REGEXP_OPERATOR_CHARS "^[$()|*+?{" |
1648 | | |
1649 | | static char * |
1650 | | sanitize_regexp(const char *old) |
1651 | 0 | { |
1652 | 0 | size_t start=0,len=strlen(old),idx=0; |
1653 | 0 | int escaped=0,standard_bracket=0; |
1654 | 0 | char *new=xmalloc((len*2)+1); /* enough to \-escape everything if we |
1655 | | have to */ |
1656 | | |
1657 | | /* There are basically two commonly-used regexps here. GPG and most |
1658 | | versions of PGP use "<[^>]+[@.]example\.com>$" and PGP (9) |
1659 | | command line uses "example.com" (i.e. whatever the user specifies, |
1660 | | and we can't expect users know to use "\." instead of "."). So |
1661 | | here are the rules: we're allowed to start with "<[^>]+[@.]" and |
1662 | | end with ">$" or start and end with nothing. In between, the |
1663 | | only legal regex character is ".", and everything else gets |
1664 | | escaped. Part of the gotcha here is that some regex packages |
1665 | | allow more than RFC-4880 requires. For example, 4880 has no "{}" |
1666 | | operator, but GNU regex does. Commenting removes these operators |
1667 | | from consideration. A possible future enhancement is to use |
1668 | | commenting to effectively back off a given regex to the Henry |
1669 | | Spencer syntax in 4880. -dshaw */ |
1670 | | |
1671 | | /* Are we bracketed between "<[^>]+[@.]" and ">$" ? */ |
1672 | 0 | if(len>=12 && strncmp(old,"<[^>]+[@.]",10)==0 |
1673 | 0 | && old[len-2]=='>' && old[len-1]=='$') |
1674 | 0 | { |
1675 | 0 | strcpy(new,"<[^>]+[@.]"); |
1676 | 0 | idx=strlen(new); |
1677 | 0 | standard_bracket=1; |
1678 | 0 | start+=10; |
1679 | 0 | len-=2; |
1680 | 0 | } |
1681 | | |
1682 | | /* Walk the remaining characters and ensure that everything that is |
1683 | | left is not an operational regex character. */ |
1684 | 0 | for(;start<len;start++) |
1685 | 0 | { |
1686 | 0 | if(!escaped && old[start]=='\\') |
1687 | 0 | escaped=1; |
1688 | 0 | else if (!escaped && strchr (REGEXP_OPERATOR_CHARS, old[start])) |
1689 | 0 | new[idx++]='\\'; |
1690 | 0 | else |
1691 | 0 | escaped=0; |
1692 | |
|
1693 | 0 | new[idx++]=old[start]; |
1694 | 0 | } |
1695 | |
|
1696 | 0 | new[idx]='\0'; |
1697 | | |
1698 | | /* Note that the (sub)string we look at might end with a bare "\". |
1699 | | If it does, leave it that way. If the regexp actually ended with |
1700 | | ">$", then it was escaping the ">" and is fine. If the regexp |
1701 | | actually ended with the bare "\", then it's an illegal regexp and |
1702 | | regcomp should kick it out. */ |
1703 | |
|
1704 | 0 | if(standard_bracket) |
1705 | 0 | strcat(new,">$"); |
1706 | |
|
1707 | 0 | return new; |
1708 | 0 | } |
1709 | | |
1710 | | |
1711 | | /* Used by validate_one_keyblock to confirm a regexp within a trust |
1712 | | * signature. Returns 1 for match, and 0 for no match or regex |
1713 | | * error. */ |
1714 | | static int |
1715 | | check_regexp (const char *expr,const char *string) |
1716 | 0 | { |
1717 | 0 | int ret; |
1718 | 0 | char *regexp; |
1719 | 0 | char *stringbuf = NULL; |
1720 | 0 | regex_t pat; |
1721 | |
|
1722 | 0 | regexp = sanitize_regexp (expr); |
1723 | |
|
1724 | 0 | ret = regcomp (&pat, regexp, (REG_ICASE|REG_EXTENDED)); |
1725 | 0 | if (!ret) |
1726 | 0 | { |
1727 | 0 | if (*regexp == '<' && !strchr (string, '<') |
1728 | 0 | && is_valid_mailbox (string)) |
1729 | 0 | { |
1730 | | /* The R.E. starts with an angle bracket but STRING seems to |
1731 | | * be a plain mailbox (e.g. "foo@example.org"). The |
1732 | | * commonly used R.E. pattern "<[^>]+[@.]example\.org>$" |
1733 | | * won't be able to detect this. Thus we enclose STRING |
1734 | | * into angle brackets for checking. */ |
1735 | 0 | stringbuf = xstrconcat ("<", string, ">", NULL); |
1736 | 0 | string = stringbuf; |
1737 | 0 | } |
1738 | 0 | ret = regexec (&pat, string, 0, NULL, 0); |
1739 | 0 | regfree (&pat); |
1740 | 0 | } |
1741 | |
|
1742 | 0 | ret = !ret; |
1743 | |
|
1744 | 0 | if (DBG_TRUST) |
1745 | 0 | log_debug ("regexp '%s' ('%s') on '%s'%s: %s\n", |
1746 | 0 | regexp, expr, string, stringbuf? " (fixed)":"", ret? "YES":"NO"); |
1747 | |
|
1748 | 0 | xfree (regexp); |
1749 | 0 | xfree (stringbuf); |
1750 | 0 | return ret; |
1751 | 0 | } |
1752 | | |
1753 | | |
1754 | | /* |
1755 | | * Return true if the key is signed by one of the keys in the given |
1756 | | * key ID list. User IDs with a valid signature are marked by node |
1757 | | * flags as follows: |
1758 | | * flag bit 0: There is at least one signature |
1759 | | * 1: There is marginal confidence that this is a legitimate uid |
1760 | | * 2: There is full confidence that this is a legitimate uid. |
1761 | | * 8: Used for internal purposes. |
1762 | | * 9: Ditto (in mark_usable_uid_certs()) |
1763 | | * 10: Ditto (ditto) |
1764 | | * This function assumes that all kbnode flags are cleared on entry. |
1765 | | */ |
1766 | | static int |
1767 | | validate_one_keyblock (ctrl_t ctrl, kbnode_t kb, struct key_item *klist, |
1768 | | u32 curtime, u32 *next_expire) |
1769 | 0 | { |
1770 | 0 | struct key_item *kr; |
1771 | 0 | KBNODE node, uidnode=NULL; |
1772 | 0 | PKT_user_id *uid=NULL; |
1773 | 0 | PKT_public_key *pk = kb->pkt->pkt.public_key; |
1774 | 0 | u32 main_kid[2]; |
1775 | 0 | int issigned=0, any_signed = 0; |
1776 | |
|
1777 | 0 | keyid_from_pk(pk, main_kid); |
1778 | 0 | for (node=kb; node; node = node->next) |
1779 | 0 | { |
1780 | | /* A bit of discussion here: is it better for the web of trust |
1781 | | to be built among only self-signed uids? On the one hand, a |
1782 | | self-signed uid is a statement that the key owner definitely |
1783 | | intended that uid to be there, but on the other hand, a |
1784 | | signed (but not self-signed) uid does carry trust, of a sort, |
1785 | | even if it is a statement being made by people other than the |
1786 | | key owner "through" the uids on the key owner's key. I'm |
1787 | | going with the latter. However, if the user ID was |
1788 | | explicitly revoked, or passively allowed to expire, that |
1789 | | should stop validity through the user ID until it is |
1790 | | resigned. -dshaw */ |
1791 | |
|
1792 | 0 | if (node->pkt->pkttype == PKT_USER_ID |
1793 | 0 | && !node->pkt->pkt.user_id->flags.revoked |
1794 | 0 | && !node->pkt->pkt.user_id->flags.expired) |
1795 | 0 | { |
1796 | 0 | if (uidnode && issigned) |
1797 | 0 | { |
1798 | 0 | if (uid->help_full_count >= opt.completes_needed |
1799 | 0 | || uid->help_marginal_count >= opt.marginals_needed ) |
1800 | 0 | uidnode->flag |= 4; |
1801 | 0 | else if (uid->help_full_count || uid->help_marginal_count) |
1802 | 0 | uidnode->flag |= 2; |
1803 | 0 | uidnode->flag |= 1; |
1804 | 0 | any_signed = 1; |
1805 | 0 | } |
1806 | 0 | uidnode = node; |
1807 | 0 | uid=uidnode->pkt->pkt.user_id; |
1808 | | |
1809 | | /* If the selfsig is going to expire... */ |
1810 | 0 | if(uid->expiredate && uid->expiredate<*next_expire) |
1811 | 0 | *next_expire = uid->expiredate; |
1812 | |
|
1813 | 0 | issigned = 0; |
1814 | 0 | get_validity_counts (ctrl, pk, uid); |
1815 | 0 | mark_usable_uid_certs (ctrl, kb, uidnode, main_kid, klist, |
1816 | 0 | curtime, next_expire); |
1817 | 0 | } |
1818 | 0 | else if (node->pkt->pkttype == PKT_SIGNATURE |
1819 | 0 | && (node->flag & (1<<8)) && uid) |
1820 | 0 | { |
1821 | | /* Note that we are only seeing unrevoked sigs here */ |
1822 | 0 | PKT_signature *sig = node->pkt->pkt.signature; |
1823 | |
|
1824 | 0 | kr = is_in_klist (klist, sig); |
1825 | | /* If the trust_regexp does not match, it's as if the sig |
1826 | | did not exist. This is safe for non-trust sigs as well |
1827 | | since we don't accept a regexp on the sig unless it's a |
1828 | | trust sig. */ |
1829 | 0 | if (kr && (!kr->trust_regexp |
1830 | 0 | || !(opt.trust_model == TM_PGP |
1831 | 0 | || opt.trust_model == TM_TOFU_PGP) |
1832 | 0 | || (uidnode |
1833 | 0 | && check_regexp(kr->trust_regexp, |
1834 | 0 | uidnode->pkt->pkt.user_id->name)))) |
1835 | 0 | { |
1836 | | /* Are we part of a trust sig chain? We always favor |
1837 | | the latest trust sig, rather than the greater or |
1838 | | lesser trust sig or value. I could make a decent |
1839 | | argument for any of these cases, but this seems to be |
1840 | | what PGP does, and I'd like to be compatible. -dms */ |
1841 | 0 | if ((opt.trust_model == TM_PGP |
1842 | 0 | || opt.trust_model == TM_TOFU_PGP) |
1843 | 0 | && sig->trust_depth |
1844 | 0 | && pk->trust_timestamp <= sig->timestamp) |
1845 | 0 | { |
1846 | 0 | unsigned char depth; |
1847 | | |
1848 | | /* If the depth on the signature is less than the |
1849 | | chain currently has, then use the signature depth |
1850 | | so we don't increase the depth beyond what the |
1851 | | signer wanted. If the depth on the signature is |
1852 | | more than the chain currently has, then use the |
1853 | | chain depth so we use as much of the signature |
1854 | | depth as the chain will permit. An ultimately |
1855 | | trusted signature can restart the depth to |
1856 | | whatever level it likes. */ |
1857 | |
|
1858 | 0 | if (sig->trust_depth < kr->trust_depth |
1859 | 0 | || kr->ownertrust == TRUST_ULTIMATE) |
1860 | 0 | depth = sig->trust_depth; |
1861 | 0 | else |
1862 | 0 | depth = kr->trust_depth; |
1863 | |
|
1864 | 0 | if (depth) |
1865 | 0 | { |
1866 | 0 | if(DBG_TRUST) |
1867 | 0 | log_debug ("trust sig on %s, sig depth is %d," |
1868 | 0 | " kr depth is %d\n", |
1869 | 0 | uidnode->pkt->pkt.user_id->name, |
1870 | 0 | sig->trust_depth, |
1871 | 0 | kr->trust_depth); |
1872 | | |
1873 | | /* If we got here, we know that: |
1874 | | |
1875 | | this is a trust sig. |
1876 | | |
1877 | | it's a newer trust sig than any previous trust |
1878 | | sig on this key (not uid). |
1879 | | |
1880 | | it is legal in that it was either generated by an |
1881 | | ultimate key, or a key that was part of a trust |
1882 | | chain, and the depth does not violate the |
1883 | | original trust sig. |
1884 | | |
1885 | | if there is a regexp attached, it matched |
1886 | | successfully. |
1887 | | */ |
1888 | |
|
1889 | 0 | if (DBG_TRUST) |
1890 | 0 | log_debug ("replacing trust value %d with %d and " |
1891 | 0 | "depth %d with %d\n", |
1892 | 0 | pk->trust_value,sig->trust_value, |
1893 | 0 | pk->trust_depth,depth); |
1894 | |
|
1895 | 0 | pk->trust_value = sig->trust_value; |
1896 | 0 | pk->trust_depth = depth-1; |
1897 | | |
1898 | | /* If the trust sig contains a regexp, record it |
1899 | | on the pk for the next round. */ |
1900 | 0 | if (sig->trust_regexp) |
1901 | 0 | pk->trust_regexp = sig->trust_regexp; |
1902 | 0 | } |
1903 | 0 | } |
1904 | |
|
1905 | 0 | if (kr->ownertrust == TRUST_ULTIMATE) |
1906 | 0 | uid->help_full_count = opt.completes_needed; |
1907 | 0 | else if (kr->ownertrust == TRUST_FULLY) |
1908 | 0 | uid->help_full_count++; |
1909 | 0 | else if (kr->ownertrust == TRUST_MARGINAL) |
1910 | 0 | uid->help_marginal_count++; |
1911 | 0 | issigned = 1; |
1912 | 0 | } |
1913 | 0 | } |
1914 | 0 | } |
1915 | |
|
1916 | 0 | if (uidnode && issigned) |
1917 | 0 | { |
1918 | 0 | if (uid->help_full_count >= opt.completes_needed |
1919 | 0 | || uid->help_marginal_count >= opt.marginals_needed ) |
1920 | 0 | uidnode->flag |= 4; |
1921 | 0 | else if (uid->help_full_count || uid->help_marginal_count) |
1922 | 0 | uidnode->flag |= 2; |
1923 | 0 | uidnode->flag |= 1; |
1924 | 0 | any_signed = 1; |
1925 | 0 | } |
1926 | |
|
1927 | 0 | return any_signed; |
1928 | 0 | } |
1929 | | |
1930 | | |
1931 | | static int |
1932 | | search_skipfnc (void *opaque, u32 *kid, int dummy_uid_no) |
1933 | 0 | { |
1934 | 0 | (void)dummy_uid_no; |
1935 | 0 | return test_key_hash_table ((KeyHashTable)opaque, kid); |
1936 | 0 | } |
1937 | | |
1938 | | |
1939 | | /* |
1940 | | * Scan all keys and return a key_array of all suitable keys from |
1941 | | * klist. The caller has to pass keydb handle so that we don't use |
1942 | | * to create our own. Returns either a key_array or NULL in case of |
1943 | | * an error. No results found are indicated by an empty array. |
1944 | | * Caller hast to release the returned array. |
1945 | | */ |
1946 | | static struct key_array * |
1947 | | validate_key_list (ctrl_t ctrl, KEYDB_HANDLE hd, KeyHashTable full_trust, |
1948 | | struct key_item *klist, u32 curtime, u32 *next_expire) |
1949 | 0 | { |
1950 | 0 | KBNODE keyblock = NULL; |
1951 | 0 | struct key_array *keys = NULL; |
1952 | 0 | size_t nkeys, maxkeys; |
1953 | 0 | int rc; |
1954 | 0 | KEYDB_SEARCH_DESC desc; |
1955 | |
|
1956 | 0 | maxkeys = 1000; |
1957 | 0 | keys = xmalloc ((maxkeys+1) * sizeof *keys); |
1958 | 0 | nkeys = 0; |
1959 | |
|
1960 | 0 | rc = keydb_search_reset (hd); |
1961 | 0 | if (rc) |
1962 | 0 | { |
1963 | 0 | log_error ("keydb_search_reset failed: %s\n", gpg_strerror (rc)); |
1964 | 0 | xfree (keys); |
1965 | 0 | return NULL; |
1966 | 0 | } |
1967 | | |
1968 | 0 | memset (&desc, 0, sizeof desc); |
1969 | 0 | desc.mode = KEYDB_SEARCH_MODE_FIRST; |
1970 | 0 | desc.skipfnc = search_skipfnc; |
1971 | 0 | desc.skipfncvalue = full_trust; |
1972 | 0 | rc = keydb_search (hd, &desc, 1, NULL); |
1973 | 0 | if (gpg_err_code (rc) == GPG_ERR_NOT_FOUND) |
1974 | 0 | { |
1975 | 0 | keys[nkeys].keyblock = NULL; |
1976 | 0 | return keys; |
1977 | 0 | } |
1978 | 0 | if (rc) |
1979 | 0 | { |
1980 | 0 | log_error ("keydb_search(first) failed: %s\n", gpg_strerror (rc)); |
1981 | 0 | goto die; |
1982 | 0 | } |
1983 | | |
1984 | 0 | desc.mode = KEYDB_SEARCH_MODE_NEXT; /* change mode */ |
1985 | 0 | do |
1986 | 0 | { |
1987 | 0 | PKT_public_key *pk; |
1988 | |
|
1989 | 0 | rc = keydb_get_keyblock (hd, &keyblock); |
1990 | 0 | if (rc) |
1991 | 0 | { |
1992 | 0 | log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (rc)); |
1993 | 0 | goto die; |
1994 | 0 | } |
1995 | | |
1996 | 0 | if ( keyblock->pkt->pkttype != PKT_PUBLIC_KEY) |
1997 | 0 | { |
1998 | 0 | log_debug ("ooops: invalid pkttype %d encountered\n", |
1999 | 0 | keyblock->pkt->pkttype); |
2000 | 0 | dump_kbnode (keyblock); |
2001 | 0 | release_kbnode(keyblock); |
2002 | 0 | continue; |
2003 | 0 | } |
2004 | | |
2005 | | /* prepare the keyblock for further processing */ |
2006 | 0 | merge_keys_and_selfsig (ctrl, keyblock); |
2007 | 0 | clear_kbnode_flags (keyblock); |
2008 | 0 | pk = keyblock->pkt->pkt.public_key; |
2009 | 0 | if (pk->has_expired || pk->flags.revoked) |
2010 | 0 | { |
2011 | | /* it does not make sense to look further at those keys */ |
2012 | 0 | mark_keyblock_seen (full_trust, keyblock); |
2013 | 0 | } |
2014 | 0 | else if (validate_one_keyblock (ctrl, keyblock, klist, |
2015 | 0 | curtime, next_expire)) |
2016 | 0 | { |
2017 | 0 | KBNODE node; |
2018 | |
|
2019 | 0 | if (pk->expiredate && pk->expiredate >= curtime |
2020 | 0 | && pk->expiredate < *next_expire) |
2021 | 0 | *next_expire = pk->expiredate; |
2022 | |
|
2023 | 0 | if (nkeys == maxkeys) { |
2024 | 0 | maxkeys += 1000; |
2025 | 0 | keys = xrealloc (keys, (maxkeys+1) * sizeof *keys); |
2026 | 0 | } |
2027 | 0 | keys[nkeys++].keyblock = keyblock; |
2028 | | |
2029 | | /* Optimization - if all uids are fully trusted, then we |
2030 | | never need to consider this key as a candidate again. */ |
2031 | |
|
2032 | 0 | for (node=keyblock; node; node = node->next) |
2033 | 0 | if (node->pkt->pkttype == PKT_USER_ID && !(node->flag & 4)) |
2034 | 0 | break; |
2035 | |
|
2036 | 0 | if(node==NULL) |
2037 | 0 | mark_keyblock_seen (full_trust, keyblock); |
2038 | |
|
2039 | 0 | keyblock = NULL; |
2040 | 0 | } |
2041 | |
|
2042 | 0 | release_kbnode (keyblock); |
2043 | 0 | keyblock = NULL; |
2044 | 0 | } |
2045 | 0 | while (!(rc = keydb_search (hd, &desc, 1, NULL))); |
2046 | | |
2047 | 0 | if (rc && gpg_err_code (rc) != GPG_ERR_NOT_FOUND) |
2048 | 0 | { |
2049 | 0 | log_error ("keydb_search_next failed: %s\n", gpg_strerror (rc)); |
2050 | 0 | goto die; |
2051 | 0 | } |
2052 | | |
2053 | 0 | keys[nkeys].keyblock = NULL; |
2054 | 0 | return keys; |
2055 | | |
2056 | 0 | die: |
2057 | 0 | keys[nkeys].keyblock = NULL; |
2058 | 0 | release_key_array (keys); |
2059 | 0 | return NULL; |
2060 | 0 | } |
2061 | | |
2062 | | /* Caller must sync */ |
2063 | | static void |
2064 | | reset_trust_records (ctrl_t ctrl) |
2065 | 2 | { |
2066 | 2 | TRUSTREC rec; |
2067 | 2 | ulong recnum; |
2068 | 2 | int count = 0, nreset = 0; |
2069 | | |
2070 | 60 | for (recnum=1; !tdbio_read_record (recnum, &rec, 0); recnum++ ) |
2071 | 58 | { |
2072 | 58 | if(rec.rectype==RECTYPE_TRUST) |
2073 | 0 | { |
2074 | 0 | count++; |
2075 | 0 | if(rec.r.trust.min_ownertrust) |
2076 | 0 | { |
2077 | 0 | rec.r.trust.min_ownertrust=0; |
2078 | 0 | write_record (ctrl, &rec); |
2079 | 0 | } |
2080 | |
|
2081 | 0 | } |
2082 | 58 | else if(rec.rectype==RECTYPE_VALID |
2083 | 58 | && ((rec.r.valid.validity&TRUST_MASK) |
2084 | 0 | || rec.r.valid.marginal_count |
2085 | 0 | || rec.r.valid.full_count)) |
2086 | 0 | { |
2087 | 0 | rec.r.valid.validity &= ~TRUST_MASK; |
2088 | 0 | rec.r.valid.marginal_count=rec.r.valid.full_count=0; |
2089 | 0 | nreset++; |
2090 | 0 | write_record (ctrl, &rec); |
2091 | 0 | } |
2092 | | |
2093 | 58 | } |
2094 | | |
2095 | 2 | if (opt.verbose) |
2096 | 0 | { |
2097 | 0 | log_info (ngettext("%d key processed", |
2098 | 0 | "%d keys processed", |
2099 | 0 | count), count); |
2100 | 0 | log_printf (ngettext(" (%d validity count cleared)\n", |
2101 | 0 | " (%d validity counts cleared)\n", |
2102 | 0 | nreset), nreset); |
2103 | 0 | } |
2104 | 2 | } |
2105 | | |
2106 | | /* |
2107 | | * Run the key validation procedure. |
2108 | | * |
2109 | | * This works this way: |
2110 | | * Step 1: Find all ultimately trusted keys (UTK). |
2111 | | * mark them all as seen and put them into klist. |
2112 | | * Step 2: loop max_cert_times |
2113 | | * Step 3: if OWNERTRUST of any key in klist is undefined |
2114 | | * ask user to assign ownertrust |
2115 | | * Step 4: Loop over all keys in the keyDB which are not marked seen |
2116 | | * Step 5: if key is revoked or expired |
2117 | | * mark key as seen |
2118 | | * continue loop at Step 4 |
2119 | | * Step 6: For each user ID of that key signed by a key in klist |
2120 | | * Calculate validity by counting trusted signatures. |
2121 | | * Set validity of user ID |
2122 | | * Step 7: If any signed user ID was found |
2123 | | * mark key as seen |
2124 | | * End Loop |
2125 | | * Step 8: Build a new klist from all fully trusted keys from step 6 |
2126 | | * End Loop |
2127 | | * Ready |
2128 | | * |
2129 | | */ |
2130 | | static int |
2131 | | validate_keys (ctrl_t ctrl, int interactive) |
2132 | 2 | { |
2133 | 2 | int rc = 0; |
2134 | 2 | int quit=0; |
2135 | 2 | struct key_item *klist = NULL; |
2136 | 2 | struct key_item *k; |
2137 | 2 | struct key_array *keys = NULL; |
2138 | 2 | struct key_array *kar; |
2139 | 2 | KEYDB_HANDLE kdb = NULL; |
2140 | 2 | KBNODE node; |
2141 | 2 | int depth; |
2142 | 2 | int ot_unknown, ot_undefined, ot_never, ot_marginal, ot_full, ot_ultimate; |
2143 | 2 | KeyHashTable stored,used,full_trust; |
2144 | 2 | u32 start_time, next_expire; |
2145 | | |
2146 | | /* Make sure we have all sigs cached. TODO: This is going to |
2147 | | require some architectural re-thinking, as it is agonizingly slow. |
2148 | | Perhaps combine this with reset_trust_records(), or only check |
2149 | | the caches on keys that are actually involved in the web of |
2150 | | trust. */ |
2151 | 2 | keydb_rebuild_caches (ctrl, 0); |
2152 | | |
2153 | 2 | kdb = keydb_new (ctrl); |
2154 | 2 | if (!kdb) |
2155 | 0 | return gpg_error_from_syserror (); |
2156 | | |
2157 | 2 | start_time = make_timestamp (); |
2158 | 2 | next_expire = 0xffffffff; /* set next expire to the year 2106 */ |
2159 | 2 | stored = new_key_hash_table (); |
2160 | 2 | used = new_key_hash_table (); |
2161 | 2 | full_trust = new_key_hash_table (); |
2162 | | |
2163 | 2 | reset_trust_records (ctrl); |
2164 | | |
2165 | | /* Fixme: Instead of always building a UTK list, we could just build it |
2166 | | * here when needed */ |
2167 | 2 | if (!utk_list) |
2168 | 2 | { |
2169 | 2 | if (!opt.quiet) |
2170 | 2 | log_info (_("no ultimately trusted keys found\n")); |
2171 | 2 | goto leave; |
2172 | 2 | } |
2173 | | |
2174 | | /* mark all UTKs as used and fully_trusted and set validity to |
2175 | | ultimate */ |
2176 | 0 | for (k=utk_list; k; k = k->next) |
2177 | 0 | { |
2178 | 0 | KBNODE keyblock; |
2179 | 0 | PKT_public_key *pk; |
2180 | |
|
2181 | 0 | keyblock = get_pubkeyblock (ctrl, k->kid); |
2182 | 0 | if (!keyblock) |
2183 | 0 | { |
2184 | 0 | log_error (_("public key of ultimately" |
2185 | 0 | " trusted key %s not found\n"), keystr(k->kid)); |
2186 | 0 | continue; |
2187 | 0 | } |
2188 | 0 | mark_keyblock_seen (used, keyblock); |
2189 | 0 | mark_keyblock_seen (stored, keyblock); |
2190 | 0 | mark_keyblock_seen (full_trust, keyblock); |
2191 | 0 | pk = keyblock->pkt->pkt.public_key; |
2192 | 0 | for (node=keyblock; node; node = node->next) |
2193 | 0 | { |
2194 | 0 | if (node->pkt->pkttype == PKT_USER_ID) |
2195 | 0 | update_validity (ctrl, pk, node->pkt->pkt.user_id, |
2196 | 0 | 0, TRUST_ULTIMATE); |
2197 | 0 | } |
2198 | 0 | if ( pk->expiredate && pk->expiredate >= start_time |
2199 | 0 | && pk->expiredate < next_expire) |
2200 | 0 | next_expire = pk->expiredate; |
2201 | |
|
2202 | 0 | release_kbnode (keyblock); |
2203 | 0 | do_sync (); |
2204 | 0 | } |
2205 | |
|
2206 | 0 | if (opt.trust_model == TM_TOFU) |
2207 | | /* In the TOFU trust model, we only need to save the ultimately |
2208 | | trusted keys. */ |
2209 | 0 | goto leave; |
2210 | | |
2211 | 0 | klist = utk_list; |
2212 | |
|
2213 | 0 | if (!opt.quiet) |
2214 | 0 | log_info ("marginals needed: %d completes needed: %d trust model: %s\n", |
2215 | 0 | opt.marginals_needed, opt.completes_needed, |
2216 | 0 | trust_model_string (opt.trust_model)); |
2217 | |
|
2218 | 0 | for (depth=0; depth < opt.max_cert_depth; depth++) |
2219 | 0 | { |
2220 | 0 | int valids=0,key_count; |
2221 | | /* See whether we should assign ownertrust values to the keys in |
2222 | | klist. */ |
2223 | 0 | ot_unknown = ot_undefined = ot_never = 0; |
2224 | 0 | ot_marginal = ot_full = ot_ultimate = 0; |
2225 | 0 | for (k=klist; k; k = k->next) |
2226 | 0 | { |
2227 | 0 | int min=0; |
2228 | | |
2229 | | /* 120 and 60 are as per RFC2440 */ |
2230 | 0 | if(k->trust_value>=120) |
2231 | 0 | min=TRUST_FULLY; |
2232 | 0 | else if(k->trust_value>=60) |
2233 | 0 | min=TRUST_MARGINAL; |
2234 | |
|
2235 | 0 | if(min!=k->min_ownertrust) |
2236 | 0 | update_min_ownertrust (ctrl, k->kid,min); |
2237 | |
|
2238 | 0 | if (interactive && k->ownertrust == TRUST_UNKNOWN) |
2239 | 0 | { |
2240 | 0 | k->ownertrust = ask_ownertrust (ctrl, k->kid,min); |
2241 | |
|
2242 | 0 | if (k->ownertrust == (unsigned int)(-1)) |
2243 | 0 | { |
2244 | 0 | quit=1; |
2245 | 0 | goto leave; |
2246 | 0 | } |
2247 | 0 | } |
2248 | | |
2249 | | /* This can happen during transition from an old trustdb |
2250 | | before trust sigs. It can also happen if a user uses two |
2251 | | different versions of GnuPG or changes the --trust-model |
2252 | | setting. */ |
2253 | 0 | if(k->ownertrust<min) |
2254 | 0 | { |
2255 | 0 | if(DBG_TRUST) |
2256 | 0 | log_debug("key %08lX%08lX:" |
2257 | 0 | " overriding ownertrust '%s' with '%s'\n", |
2258 | 0 | (ulong)k->kid[0],(ulong)k->kid[1], |
2259 | 0 | trust_value_to_string(k->ownertrust), |
2260 | 0 | trust_value_to_string(min)); |
2261 | |
|
2262 | 0 | k->ownertrust=min; |
2263 | 0 | } |
2264 | |
|
2265 | 0 | if (k->ownertrust == TRUST_UNKNOWN) |
2266 | 0 | ot_unknown++; |
2267 | 0 | else if (k->ownertrust == TRUST_UNDEFINED) |
2268 | 0 | ot_undefined++; |
2269 | 0 | else if (k->ownertrust == TRUST_NEVER) |
2270 | 0 | ot_never++; |
2271 | 0 | else if (k->ownertrust == TRUST_MARGINAL) |
2272 | 0 | ot_marginal++; |
2273 | 0 | else if (k->ownertrust == TRUST_FULLY) |
2274 | 0 | ot_full++; |
2275 | 0 | else if (k->ownertrust == TRUST_ULTIMATE) |
2276 | 0 | ot_ultimate++; |
2277 | |
|
2278 | 0 | valids++; |
2279 | 0 | } |
2280 | | |
2281 | | /* Find all keys which are signed by a key in kdlist */ |
2282 | 0 | keys = validate_key_list (ctrl, kdb, full_trust, klist, |
2283 | 0 | start_time, &next_expire); |
2284 | 0 | if (!keys) |
2285 | 0 | { |
2286 | 0 | log_error ("validate_key_list failed\n"); |
2287 | 0 | rc = GPG_ERR_GENERAL; |
2288 | 0 | goto leave; |
2289 | 0 | } |
2290 | | |
2291 | 0 | for (key_count=0, kar=keys; kar->keyblock; kar++, key_count++) |
2292 | 0 | ; |
2293 | | |
2294 | | /* Store the calculated valididation status somewhere */ |
2295 | 0 | if (opt.verbose > 1 && DBG_TRUST) |
2296 | 0 | dump_key_array (depth, keys); |
2297 | |
|
2298 | 0 | for (kar=keys; kar->keyblock; kar++) |
2299 | 0 | store_validation_status (ctrl, depth, kar->keyblock, stored); |
2300 | |
|
2301 | 0 | if (!opt.quiet) |
2302 | 0 | log_info (_("depth: %d valid: %3d signed: %3d" |
2303 | 0 | " trust: %d-, %dq, %dn, %dm, %df, %du\n"), |
2304 | 0 | depth, valids, key_count, ot_unknown, ot_undefined, |
2305 | 0 | ot_never, ot_marginal, ot_full, ot_ultimate ); |
2306 | | |
2307 | | /* Build a new kdlist from all fully valid keys in KEYS */ |
2308 | 0 | if (klist != utk_list) |
2309 | 0 | release_key_items (klist); |
2310 | 0 | klist = NULL; |
2311 | 0 | for (kar=keys; kar->keyblock; kar++) |
2312 | 0 | { |
2313 | 0 | for (node=kar->keyblock; node; node = node->next) |
2314 | 0 | { |
2315 | 0 | if (node->pkt->pkttype == PKT_USER_ID && (node->flag & 4)) |
2316 | 0 | { |
2317 | 0 | u32 kid[2]; |
2318 | | |
2319 | | /* have we used this key already? */ |
2320 | 0 | keyid_from_pk (kar->keyblock->pkt->pkt.public_key, kid); |
2321 | 0 | if(test_key_hash_table(used,kid)==0) |
2322 | 0 | { |
2323 | | /* Normally we add both the primary and subkey |
2324 | | ids to the hash via mark_keyblock_seen, but |
2325 | | since we aren't using this hash as a skipfnc, |
2326 | | that doesn't matter here. */ |
2327 | 0 | add_key_hash_table (used,kid); |
2328 | 0 | k = new_key_item (); |
2329 | 0 | k->kid[0]=kid[0]; |
2330 | 0 | k->kid[1]=kid[1]; |
2331 | 0 | k->ownertrust = |
2332 | 0 | (tdb_get_ownertrust |
2333 | 0 | (ctrl, kar->keyblock->pkt->pkt.public_key, 0) |
2334 | 0 | & TRUST_MASK); |
2335 | 0 | k->min_ownertrust = tdb_get_min_ownertrust |
2336 | 0 | (ctrl, kar->keyblock->pkt->pkt.public_key, 0); |
2337 | 0 | k->trust_depth= |
2338 | 0 | kar->keyblock->pkt->pkt.public_key->trust_depth; |
2339 | 0 | k->trust_value= |
2340 | 0 | kar->keyblock->pkt->pkt.public_key->trust_value; |
2341 | 0 | if(kar->keyblock->pkt->pkt.public_key->trust_regexp) |
2342 | 0 | k->trust_regexp= |
2343 | 0 | xstrdup(kar->keyblock->pkt-> |
2344 | 0 | pkt.public_key->trust_regexp); |
2345 | 0 | k->next = klist; |
2346 | 0 | klist = k; |
2347 | 0 | break; |
2348 | 0 | } |
2349 | 0 | } |
2350 | 0 | } |
2351 | 0 | } |
2352 | 0 | release_key_array (keys); |
2353 | 0 | keys = NULL; |
2354 | 0 | if (!klist) |
2355 | 0 | break; /* no need to dive in deeper */ |
2356 | 0 | } |
2357 | | |
2358 | 2 | leave: |
2359 | 2 | keydb_release (kdb); |
2360 | 2 | release_key_array (keys); |
2361 | 2 | if (klist != utk_list) |
2362 | 0 | release_key_items (klist); |
2363 | 2 | release_key_hash_table (full_trust); |
2364 | 2 | release_key_hash_table (used); |
2365 | 2 | release_key_hash_table (stored); |
2366 | 2 | if (!rc && !quit) /* mark trustDB as checked */ |
2367 | 2 | { |
2368 | 2 | int rc2; |
2369 | | |
2370 | 2 | if (next_expire == 0xffffffff || next_expire < start_time ) |
2371 | 2 | tdbio_write_nextcheck (ctrl, 0); |
2372 | 0 | else |
2373 | 0 | { |
2374 | 0 | tdbio_write_nextcheck (ctrl, next_expire); |
2375 | 0 | if (!opt.quiet) |
2376 | 0 | log_info (_("next trustdb check due at %s\n"), |
2377 | 0 | strtimestamp (next_expire)); |
2378 | 0 | } |
2379 | | |
2380 | 2 | rc2 = tdbio_update_version_record (ctrl); |
2381 | 2 | if (rc2) |
2382 | 0 | { |
2383 | 0 | log_error (_("unable to update trustdb version record: " |
2384 | 0 | "write failed: %s\n"), gpg_strerror (rc2)); |
2385 | 0 | tdbio_invalid (); |
2386 | 0 | } |
2387 | | |
2388 | 2 | do_sync (); |
2389 | 2 | pending_check_trustdb = 0; |
2390 | 2 | } |
2391 | | |
2392 | 2 | return rc; |
2393 | 0 | } |