Implemented the chain model for X.509 validation.
[gnupg.git] / agent / trustlist.c
1 /* trustlist.c - Maintain the list of trusted keys
2  * Copyright (C) 2002, 2004, 2006, 2007 Free Software Foundation, Inc.
3  *
4  * This file is part of GnuPG.
5  *
6  * GnuPG is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * GnuPG is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include <config.h>
21 #include <errno.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <ctype.h>
26 #include <assert.h>
27 #include <unistd.h>
28 #include <sys/stat.h>
29 #include <pth.h>
30
31 #include "agent.h"
32 #include <assuan.h> /* fixme: need a way to avoid assuan calls here */
33 #include "i18n.h"
34
35
36 /* A structure to store the information from the trust file. */
37 struct trustitem_s
38 {
39   struct
40   {
41     int for_pgp:1;        /* Set by '*' or 'P' as first flag. */
42     int for_smime:1;      /* Set by '*' or 'S' as first flag. */
43     int relax:1;          /* Relax checking of root certificate
44                              constraints. */
45     int cm:1;             /* Use chain model for validation. */
46   } flags;
47   unsigned char fpr[20];  /* The binary fingerprint. */
48 };
49 typedef struct trustitem_s trustitem_t;
50
51 /* Malloced table and its allocated size with all trust items. */
52 static trustitem_t *trusttable; 
53 static size_t trusttablesize; 
54 /* A mutex used to protect the table. */
55 static pth_mutex_t trusttable_lock;
56
57
58
59 static const char headerblurb[] =
60 "# This is the list of trusted keys.  Comment lines, like this one, as\n"
61 "# well as empty lines are ignored.  Lines have a length limit but this\n"
62 "# is not serious limitation as the format of the entries is fixed and\n"
63 "# checked by gpg-agent.  A non-comment line starts with optional white\n"
64 "# space, followed by the SHA-1 fingerpint in hex, optionally followed\n"
65 "# by a flag character which my either be 'P', 'S' or '*'.  You should\n"
66 "# give the gpg-agent a HUP after editing this file.\n"
67 "\n\n"
68 "# Include the default trust list\n"
69 "include-default\n"
70 "\n";
71
72
73 /* This function must be called once to initialize this module.  This
74    has to be done before a second thread is spawned.  We can't do the
75    static initialization because Pth emulation code might not be able
76    to do a static init; in particular, it is not possible for W32. */
77 void
78 initialize_module_trustlist (void)
79 {
80   static int initialized;
81
82   if (!initialized)
83     {
84       if (!pth_mutex_init (&trusttable_lock))
85         log_fatal ("error initializing mutex: %s\n", strerror (errno));
86       initialized = 1;
87     }
88 }
89
90
91
92 \f
93 static void
94 lock_trusttable (void)
95 {
96   if (!pth_mutex_acquire (&trusttable_lock, 0, NULL))
97     log_fatal ("failed to acquire mutex in %s\n", __FILE__);
98 }
99
100 static void
101 unlock_trusttable (void)
102 {
103   if (!pth_mutex_release (&trusttable_lock))
104     log_fatal ("failed to release mutex in %s\n", __FILE__);
105 }
106
107
108
109 static gpg_error_t
110 read_one_trustfile (const char *fname, int allow_include,
111                     trustitem_t **addr_of_table, 
112                     size_t *addr_of_tablesize,
113                     int *addr_of_tableidx)
114 {
115   gpg_error_t err = 0;
116   FILE *fp;
117   int n, c;
118   char *p, line[256];
119   trustitem_t *table, *ti;
120   int tableidx;
121   size_t tablesize;
122   int lnr = 0;
123
124   table = *addr_of_table;
125   tablesize = *addr_of_tablesize;
126   tableidx = *addr_of_tableidx;
127
128   fp = fopen (fname, "r");
129   if (!fp)
130     {
131       err = gpg_error_from_syserror ();
132       log_error (_("error opening `%s': %s\n"), fname, gpg_strerror (err));
133       goto leave;
134     }
135
136   while (fgets (line, DIM(line)-1, fp))
137     {
138       lnr++;
139       
140       if (!*line || line[strlen(line)-1] != '\n')
141         {
142           /* Eat until end of line. */
143           while ( (c=getc (fp)) != EOF && c != '\n')
144             ;
145           err = gpg_error (*line? GPG_ERR_LINE_TOO_LONG
146                            : GPG_ERR_INCOMPLETE_LINE);
147           log_error (_("file `%s', line %d: %s\n"),
148                      fname, lnr, gpg_strerror (err));
149           continue;
150         }
151       line[strlen(line)-1] = 0; /* Chop the LF. */
152       
153       /* Allow for empty lines and spaces */
154       for (p=line; spacep (p); p++)
155         ;
156       if (!*p || *p == '#')
157         continue;
158   
159       if (!strncmp (p, "include-default", 15)
160           && (!p[15] || spacep (p+15)))
161         {
162           char *etcname;
163           gpg_error_t err2;
164
165           if (!allow_include)
166             {
167               log_error (_("statement \"%s\" ignored in `%s', line %d\n"),
168                          "include-default", fname, lnr);
169               continue;
170             }
171           /* fixme: Should check for trailing garbage.  */
172
173           etcname = make_filename (gnupg_sysconfdir (), "trustlist.txt", NULL);
174           if ( !strcmp (etcname, fname) ) /* Same file. */
175             log_info (_("statement \"%s\" ignored in `%s', line %d\n"),
176                       "include-default", fname, lnr);
177           else if ( access (etcname, F_OK) && errno == ENOENT )
178             {
179               /* A non existent system trustlist is not an error.
180                  Just print a note. */
181               log_info (_("system trustlist `%s' not available\n"), etcname);
182             }
183           else
184             {
185               err2 = read_one_trustfile (etcname, 0,
186                                          &table, &tablesize, &tableidx);
187               if (err2)
188                 err = err2;
189             }
190           xfree (etcname);
191           
192           continue;
193         }
194
195       if (tableidx == tablesize)  /* Need more space. */
196         {
197           trustitem_t *tmp;
198           size_t tmplen;
199           
200           tmplen = tablesize + 20;
201           tmp = xtryrealloc (table, tmplen * sizeof *table);
202           if (!tmp)
203             {
204               err = gpg_error_from_syserror ();
205               goto leave;
206             }
207           table = tmp;
208           tablesize = tmplen;
209         }
210
211       ti = table + tableidx;
212
213       n = hexcolon2bin (p, ti->fpr, 20);
214       if (n < 0)
215         {
216           log_error (_("bad fingerprint in `%s', line %d\n"), fname, lnr);
217           err = gpg_error (GPG_ERR_BAD_DATA); 
218           continue;
219         }
220       p += n;
221       for (; spacep (p); p++)
222         ;
223       
224       memset (&ti->flags, 0, sizeof ti->flags);
225       /* Process the first flag which needs to be the first for
226          backward compatibility. */
227       if (!*p || *p == '*' )
228         {
229           ti->flags.for_smime = 1;
230           ti->flags.for_pgp = 1;
231         }
232       else if ( *p == 'P' || *p == 'p')
233         {
234           ti->flags.for_pgp = 1;
235         }
236       else if ( *p == 'S' || *p == 's')
237         {
238           ti->flags.for_smime = 1;
239         }
240       else
241         {
242           log_error (_("invalid keyflag in `%s', line %d\n"), fname, lnr);
243           err = gpg_error (GPG_ERR_BAD_DATA);
244           continue;
245         }
246       p++;
247       if ( *p && !spacep (p) )
248         {
249           log_error (_("invalid keyflag in `%s', line %d\n"), fname, lnr);
250           err = gpg_error (GPG_ERR_BAD_DATA);
251           continue;
252         }
253
254       /* Now check for more key-value pairs of the form NAME[=VALUE]. */
255       while (*p)
256         {
257           for (; spacep (p); p++)
258             ;
259           if (!*p)
260             break;
261           n = strcspn (p, "= \t");
262           if (p[n] == '=')
263             {
264               log_error ("assigning a value to a flag is not yet supported; "
265                          "in `%s', line %d\n", fname, lnr);
266               err = gpg_error (GPG_ERR_BAD_DATA);
267               p++;
268             }
269           else if (n == 5 && !memcmp (p, "relax", 5))
270             ti->flags.relax = 1;
271           else if (n == 2 && !memcmp (p, "cm", 2))
272             ti->flags.cm = 1;
273           else
274             log_error ("flag `%.*s' in `%s', line %d ignored\n",
275                        n, p, fname, lnr);
276           p += n;
277         }
278       tableidx++;
279     }
280   if ( !err && !feof (fp) )
281     {
282       err = gpg_error_from_syserror ();
283       log_error (_("error reading `%s', line %d: %s\n"),
284                  fname, lnr, gpg_strerror (err));
285     }
286
287  leave:
288   if (fp)
289     fclose (fp);
290   *addr_of_table = table;
291   *addr_of_tablesize = tablesize;
292   *addr_of_tableidx = tableidx;
293   return err;
294 }
295
296
297 /* Read the trust files and update the global table on success.  */
298 static gpg_error_t
299 read_trustfiles (void)
300 {
301   gpg_error_t err;
302   trustitem_t *table, *ti;
303   int tableidx;
304   size_t tablesize;
305   char *fname;
306   int allow_include = 1;
307
308   tablesize = 20;
309   table = xtrycalloc (tablesize, sizeof *table);
310   if (!table)
311     return gpg_error_from_syserror ();
312   tableidx = 0;
313
314   fname = make_filename (opt.homedir, "trustlist.txt", NULL);
315   if ( access (fname, F_OK) )
316     {
317       if ( errno == ENOENT )
318         ; /* Silently ignore a non-existing trustfile.  */
319       else
320         {
321           err = gpg_error_from_syserror ();
322           log_error (_("error opening `%s': %s\n"), fname, gpg_strerror (err));
323         }
324       xfree (fname);
325       fname = make_filename (gnupg_sysconfdir (), "trustlist.txt", NULL);
326       allow_include = 0;
327     }
328   err = read_one_trustfile (fname, allow_include,
329                             &table, &tablesize, &tableidx);
330   xfree (fname);
331
332   if (err)
333     {
334       xfree (table);
335       if (gpg_err_code (err) == GPG_ERR_ENOENT)
336         {
337           /* Take a missing trustlist as an empty one.  */
338           lock_trusttable ();
339           xfree (trusttable);
340           trusttable = NULL;
341           trusttablesize = 0;
342           unlock_trusttable ();
343           err = 0;
344         }
345       return err;
346     }
347
348   /* Fixme: we should drop duplicates and sort the table. */
349   ti = xtryrealloc (table, (tableidx?tableidx:1) * sizeof *table);
350   if (!ti)
351     {
352       xfree (table);
353       return err;
354     }
355
356   lock_trusttable ();
357   xfree (trusttable);
358   trusttable = table;
359   trusttablesize = tableidx;
360   unlock_trusttable ();
361   return 0;
362 }
363
364
365
366 /* Check whether the given fpr is in our trustdb.  We expect FPR to be
367    an all uppercase hexstring of 40 characters. */
368 gpg_error_t 
369 agent_istrusted (ctrl_t ctrl, const char *fpr)
370 {
371   gpg_error_t err;
372   trustitem_t *ti;
373   size_t len;
374   unsigned char fprbin[20];
375
376   if ( hexcolon2bin (fpr, fprbin, 20) < 0 )
377     return gpg_error (GPG_ERR_INV_VALUE);
378
379   if (!trusttable)
380     {
381       err = read_trustfiles ();
382       if (err)
383         {
384           log_error (_("error reading list of trusted root certificates\n"));
385           return err;
386         }
387     }
388
389   if (trusttable)
390     {
391       for (ti=trusttable, len = trusttablesize; len; ti++, len--)
392         if (!memcmp (ti->fpr, fprbin, 20))
393           {
394             if (ti->flags.relax)
395               {
396                 err = agent_write_status (ctrl,
397                                           "TRUSTLISTFLAG", "relax", 
398                                           NULL);
399                 if (err)
400                   return err;
401               }
402             else if (ti->flags.cm)
403               {
404                 err = agent_write_status (ctrl,
405                                           "TRUSTLISTFLAG", "cm", 
406                                           NULL);
407                 if (err)
408                   return err;
409               }
410             return 0; /* Trusted. */
411           }
412     }
413   return gpg_error (GPG_ERR_NOT_TRUSTED);
414 }
415
416
417 /* Write all trust entries to FP. */
418 gpg_error_t 
419 agent_listtrusted (void *assuan_context)
420 {
421   trustitem_t *ti;
422   char key[51];
423   gpg_error_t err;
424   size_t len;
425
426   if (!trusttable)
427     {
428       err = read_trustfiles ();
429       if (err)
430         {
431           log_error (_("error reading list of trusted root certificates\n"));
432           return err;
433         }
434     }
435
436   if (trusttable)
437     {
438       /* We need to lock the table because the scheduler may interrupt
439          assuan_send_data and an other thread may then re-read the table. */
440       lock_trusttable ();
441       for (ti=trusttable, len = trusttablesize; len; ti++, len--)
442         {
443           bin2hex (ti->fpr, 20, key);
444           key[40] = ' ';
445           key[41] = ((ti->flags.for_smime && ti->flags.for_pgp)? '*'
446                      : ti->flags.for_smime? 'S': ti->flags.for_pgp? 'P':' ');
447           key[42] = '\n';
448           assuan_send_data (assuan_context, key, 43);
449           assuan_send_data (assuan_context, NULL, 0); /* flush */
450         }
451       unlock_trusttable ();
452     }
453
454   return 0;
455 }
456
457
458 /* Insert the given fpr into our trustdb.  We expect FPR to be an all
459    uppercase hexstring of 40 characters. FLAG is either 'P' or 'C'.
460    This function does first check whether that key has alreay been put
461    into the trustdb and returns success in this case.  Before a FPR
462    actually gets inserted, the user is asked by means of the pin-entry
463    whether this is actual wants he want to do.
464 */
465 gpg_error_t
466 agent_marktrusted (ctrl_t ctrl, const char *name, const char *fpr, int flag)
467 {
468   gpg_error_t err = 0;
469   char *desc;
470   char *fname;
471   FILE *fp;
472
473   /* Check whether we are at all allowed to modify the trustlist.
474      This is useful so that the trustlist may be a symlink to a global
475      trustlist with only admin priviliges to modify it.  Of course
476      this is not a secure way of denying access, but it avoids the
477      usual clicking on an Okay button most users are used to. */
478   fname = make_filename (opt.homedir, "trustlist.txt", NULL);
479   if ( access (fname, W_OK) && errno != ENOENT)
480     {
481       xfree (fname);
482       return gpg_error (GPG_ERR_EPERM);
483     }    
484   xfree (fname);
485
486   if (!agent_istrusted (ctrl, fpr))
487     {
488       return 0; /* We already got this fingerprint.  Silently return
489                    success. */
490     }
491
492   /* This feature must explicitly been enabled. */
493   if (!opt.allow_mark_trusted)
494     return gpg_error (GPG_ERR_NOT_SUPPORTED);
495
496   /* Insert a new one. */
497   if (asprintf (&desc,
498                 /* TRANSLATORS: This prompt is shown by the Pinentry
499                    and has one special property: A "%%0A" is used by
500                    Pinentry to insert a line break.  The double
501                    percent sign is actually needed because it is also
502                    a printf format string.  If you need to insert a
503                    plain % sign, you need to encode it as "%%25".  The
504                    second "%s" gets replaced by a hexdecimal
505                    fingerprint string whereas the first one receives
506                    the name as store in the certificate. */
507                 _("Please verify that the certificate identified as:%%0A"
508                   "  \"%s\"%%0A"
509                   "has the fingerprint:%%0A"
510                   "  %s"), name, fpr) < 0 )
511     return out_of_core ();
512
513   /* TRANSLATORS: "Correct" is the label of a button and intended to
514      be hit if the fingerprint matches the one of the CA.  The other
515      button is "the default "Cancel" of the Pinentry. */
516   err = agent_get_confirmation (ctrl, desc, _("Correct"), NULL);
517   free (desc);
518   /* If the user did not confirmed this, we return cancel here so that
519      gpgsm may stop asking further questions.  We won't do this for
520      the second question of course. */
521   if (err)
522     return (gpg_err_code (err) == GPG_ERR_NOT_CONFIRMED ? 
523             gpg_err_make (gpg_err_source (err), GPG_ERR_CANCELED) : err);
524
525
526
527   if (asprintf (&desc,
528                 /* TRANSLATORS: This prompt is shown by the Pinentry
529                    and has one special property: A "%%0A" is used by
530                    Pinentry to insert a line break.  The double
531                    percent sign is actually needed because it is also
532                    a printf format string.  If you need to insert a
533                    plain % sign, you need to encode it as "%%25".  The
534                    "%s" gets replaced by the name as store in the
535                    certificate. */
536                 _("Do you ultimately trust%%0A"
537                   "  \"%s\"%%0A"
538                   "to correctly certify user certificates?"),
539                 name) < 0 )
540     return out_of_core ();
541
542   err = agent_get_confirmation (ctrl, desc, _("Yes"), _("No"));
543   free (desc);
544   if (err)
545     return err;
546
547   /* Now check again to avoid duplicates.  We take the lock to make
548      sure that nobody else plays with our file.  Frankly we don't work
549      with the trusttable but using this lock is just fine for our
550      purpose.  */
551   lock_trusttable ();
552   if (!agent_istrusted (ctrl, fpr))
553     {
554       unlock_trusttable ();
555       return 0; 
556     }
557
558
559   fname = make_filename (opt.homedir, "trustlist.txt", NULL);
560   if ( access (fname, F_OK) && errno == ENOENT)
561     {
562       fp = fopen (fname, "wx"); /* Warning: "x" is a GNU extension. */
563       if (!fp)
564         {
565           err = gpg_error_from_syserror ();
566           log_error ("can't create `%s': %s\n", fname, gpg_strerror (err));
567           xfree (fname);
568           unlock_trusttable ();
569           return err;
570         }
571       fputs (headerblurb, fp);
572       fclose (fp);
573     }
574   fp = fopen (fname, "a+");
575   if (!fp)
576     {
577       err = gpg_error_from_syserror ();
578       log_error ("can't open `%s': %s\n", fname, gpg_strerror (err));
579       xfree (fname);
580       unlock_trusttable ();
581       return err;
582     }
583
584   /* Append the key. */
585   fputs ("\n# ", fp);
586   print_sanitized_string (fp, name, 0);
587   fprintf (fp, "\n%s %c\n", fpr, flag);
588   if (ferror (fp))
589     err = gpg_error_from_syserror ();
590   
591   if (fclose (fp))
592     err = gpg_error_from_syserror ();
593
594   if (!err)
595     agent_reload_trustlist ();
596   xfree (fname);
597   unlock_trusttable ();
598   return err;
599 }
600
601
602 /* This function may be called to force reloading of the
603    trustlist.  */
604 void
605 agent_reload_trustlist (void)
606 {
607   /* All we need to do is to delete the trusttable.  At the next
608      access it will get re-read. */
609   lock_trusttable ();
610   xfree (trusttable);
611   trusttable = NULL;
612   trusttablesize = 0;
613   unlock_trusttable ();
614   bump_key_eventcounter ();
615 }