* certpath.c (gpgsm_walk_cert_chain): Be a bit more silent on
[gnupg.git] / sm / certchain.c
1 /* certpath.c - path validation
2  *      Copyright (C) 2001 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 2 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, write to the Free Software
18  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
19  */
20
21 #include <config.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <errno.h>
26 #include <unistd.h> 
27 #include <time.h>
28 #include <assert.h>
29
30 #include <gcrypt.h>
31 #include <ksba.h>
32
33 #include "gpgsm.h"
34 #include "keydb.h"
35 #include "i18n.h"
36
37 static int
38 unknown_criticals (KsbaCert cert)
39 {
40   static const char *known[] = {
41     "2.5.29.15", /* keyUsage */
42     "2.5.29.19", /* basic Constraints */
43     "2.5.29.32", /* certificatePolicies */
44     NULL
45   };
46   int rc = 0, i, idx, crit;
47   const char *oid;
48   KsbaError err;
49
50   for (idx=0; !(err=ksba_cert_get_extension (cert, idx,
51                                              &oid, &crit, NULL, NULL));idx++)
52     {
53       if (!crit)
54         continue;
55       for (i=0; known[i] && strcmp (known[i],oid); i++)
56         ;
57       if (!known[i])
58         {
59           log_error (_("critical certificate extension %s is not supported\n"),
60                      oid);
61           rc = GNUPG_Unsupported_Certificate;
62         }
63     }
64   if (err && err != -1)
65     rc = map_ksba_err (err);
66
67   return rc;
68 }
69
70 static int
71 allowed_ca (KsbaCert cert, int *pathlen)
72 {
73   KsbaError err;
74   int flag;
75
76   err = ksba_cert_is_ca (cert, &flag, pathlen);
77   if (err)
78     return map_ksba_err (err);
79   if (!flag)
80     {
81       log_error (_("issuer certificate is not marked as a CA\n"));
82       return GNUPG_Bad_CA_Certificate;
83     }
84   return 0;
85 }
86
87
88 static int
89 check_cert_policy (KsbaCert cert)
90 {
91   KsbaError err;
92   char *policies;
93   FILE *fp;
94   int any_critical;
95
96   err = ksba_cert_get_cert_policies (cert, &policies);
97   if (err == KSBA_No_Data)
98     return 0; /* no policy given */
99   if (err)
100     return map_ksba_err (err);
101
102   /* STRING is a line delimited list of certifiate policies as stored
103      in the certificate.  The line itself is colon delimited where the
104      first field is the OID of the policy and the second field either
105      N or C for normal or critical extension */
106
107   if (opt.verbose > 1)
108     log_info ("certificate's policy list: %s\n", policies);
109
110   /* The check is very minimal but won't give false positives */
111   any_critical = !!strstr (policies, ":C");
112
113   if (!opt.policy_file)
114     { 
115       xfree (policies);
116       if (any_critical)
117         {
118           log_error ("critical marked policy without configured policies\n");
119           return GNUPG_No_Policy_Match;
120         }
121       return 0;
122     }
123
124   fp = fopen (opt.policy_file, "r");
125   if (!fp)
126     {
127       log_error ("failed to open `%s': %s\n",
128                  opt.policy_file, strerror (errno));
129       xfree (policies);
130       return GNUPG_Configuration_Error;
131     }
132
133   for (;;) 
134     {
135       int c;
136       char *p, line[256];
137       char *haystack, *allowed;
138
139       /* read line */
140       do
141         {
142           if (!fgets (line, DIM(line)-1, fp) )
143             {
144               xfree (policies);
145               if (feof (fp))
146                 {
147                   fclose (fp);
148                   log_error (_("certificate policy not allowed\n"));
149                   /* with no critical policies this is only a warning */
150                   return any_critical? GNUPG_No_Policy_Match : 0;
151                 }
152               fclose (fp);
153               return GNUPG_Read_Error;
154             }
155       
156           if (!*line || line[strlen(line)-1] != '\n')
157             {
158               /* eat until end of line */
159               while ( (c=getc (fp)) != EOF && c != '\n')
160                 ;
161               fclose (fp);
162               xfree (policies);
163               return *line? GNUPG_Line_Too_Long: GNUPG_Incomplete_Line;
164             }
165           
166           /* Allow for empty lines and spaces */
167           for (p=line; spacep (p); p++)
168             ;
169         }
170       while (!*p || *p == '\n' || *p == '#');
171   
172       /* parse line */
173       for (allowed=line; spacep (allowed); allowed++)
174         ;
175       p = strpbrk (allowed, " :\n");
176       if (!*p || p == allowed)
177         {
178           fclose (fp);
179           xfree (policies);
180           return GNUPG_Configuration_Error;
181         }
182       *p = 0; /* strip the rest of the line */
183       /* See whether we find ALLOWED (which is an OID) in POLICIES */
184       for (haystack=policies; (p=strstr (haystack, allowed)); haystack = p+1)
185         {
186           if ( !(p == policies || p[-1] == '\n') )
187             continue; /* does not match the begin of a line */
188           if (p[strlen (allowed)] != ':')
189             continue; /* the length does not match */
190           /* Yep - it does match so return okay */
191           fclose (fp);
192           xfree (policies);
193           return 0;
194         }
195     }
196 }
197
198 /* Return the next certificate up in the chain starting at START.
199    Returns -1 when there are no more certificates. */
200 int
201 gpgsm_walk_cert_chain (KsbaCert start, KsbaCert *r_next)
202 {
203   int rc = 0; 
204   char *issuer = NULL;
205   char *subject = NULL;
206   KEYDB_HANDLE kh = keydb_new (0);
207
208   *r_next = NULL;
209   if (!kh)
210     {
211       log_error (_("failed to allocated keyDB handle\n"));
212       rc = GNUPG_General_Error;
213       goto leave;
214     }
215
216   issuer = ksba_cert_get_issuer (start, 0);
217   subject = ksba_cert_get_subject (start, 0);
218   if (!issuer)
219     {
220       log_error ("no issuer found in certificate\n");
221       rc = GNUPG_Bad_Certificate;
222       goto leave;
223     }
224   if (!subject)
225     {
226       log_error ("no subject found in certificate\n");
227       rc = GNUPG_Bad_Certificate;
228       goto leave;
229     }
230
231   if (!strcmp (issuer, subject))
232     {
233       rc = -1; /* we are at the root */
234       goto leave; 
235     }
236  
237   rc = keydb_search_subject (kh, issuer);
238   if (rc)
239     {
240       /* it is quite common not to have a certificate, so better don't
241          print an error here */
242       if (rc != -1 && opt.verbose > 1)
243         log_error ("failed to find issuer's certificate: rc=%d\n", rc);
244       rc = GNUPG_Missing_Certificate;
245       goto leave;
246     }
247
248   rc = keydb_get_cert (kh, r_next);
249   if (rc)
250     {
251       log_error ("failed to get cert: rc=%d\n", rc);
252       rc = GNUPG_General_Error;
253     }
254
255  leave:
256   xfree (issuer);
257   xfree (subject);
258   keydb_release (kh); 
259   return rc;
260 }
261
262
263 /* Check whether the CERT is a root certificate.  Returns True if this
264    is the case. */
265 int
266 gpgsm_is_root_cert (KsbaCert cert)
267 {
268   char *issuer;
269   char *subject;
270   int yes;
271
272   issuer = ksba_cert_get_issuer (cert, 0);
273   subject = ksba_cert_get_subject (cert, 0);
274   yes = (issuer && subject && !strcmp (issuer, subject));
275   xfree (issuer);
276   xfree (subject);
277   return yes;
278 }
279
280 \f
281 int
282 gpgsm_validate_path (KsbaCert cert)
283 {
284   int rc = 0, depth = 0, maxdepth;
285   char *issuer = NULL;
286   char *subject = NULL;
287   KEYDB_HANDLE kh = keydb_new (0);
288   KsbaCert subject_cert = NULL, issuer_cert = NULL;
289   time_t current_time = time (NULL);
290
291   if ((opt.debug & 4096))
292     {
293       log_info ("WARNING: bypassing path validation\n");
294       return 0;
295     }
296       
297
298   if (!kh)
299     {
300       log_error (_("failed to allocated keyDB handle\n"));
301       rc = GNUPG_General_Error;
302       goto leave;
303     }
304
305   if (DBG_X509)
306     gpgsm_dump_cert ("subject", cert);
307
308   subject_cert = cert;
309   maxdepth = 50;
310
311   for (;;)
312     {
313       xfree (issuer);
314       xfree (subject);
315       issuer = ksba_cert_get_issuer (subject_cert, 0);
316       subject = ksba_cert_get_subject (subject_cert, 0);
317
318       if (!issuer)
319         {
320           log_error ("no issuer found in certificate\n");
321           rc = GNUPG_Bad_Certificate;
322           goto leave;
323         }
324
325       {
326         time_t not_before, not_after;
327
328         not_before = ksba_cert_get_validity (subject_cert, 0);
329         not_after = ksba_cert_get_validity (subject_cert, 1);
330         if (not_before == (time_t)(-1) || not_after == (time_t)(-1))
331           {
332             log_error ("certificate with invalid validity\n");
333             rc = GNUPG_Bad_Certificate;
334             goto leave;
335           }
336
337         if (current_time < not_before)
338           {
339             log_error ("certificate to young; valid from ");
340             gpgsm_dump_time (not_before);
341             log_printf ("\n");
342             rc = GNUPG_Certificate_Too_Young;
343             goto leave;
344           }            
345         if (current_time > not_after)
346           {
347             log_error ("certificate has expired at ");
348             gpgsm_dump_time (not_after);
349             log_printf ("\n");
350             rc = GNUPG_Certificate_Expired;
351             goto leave;
352           }            
353       }
354
355       rc = unknown_criticals (subject_cert);
356       if (rc)
357         goto leave;
358
359       if (!opt.no_policy_check)
360         {
361           rc = check_cert_policy (subject_cert);
362           if (rc)
363             goto leave;
364         }
365
366       if (!opt.no_crl_check)
367         {
368           rc = gpgsm_dirmngr_isvalid (subject_cert);
369           if (rc)
370             {
371               switch (rc)
372                 {
373                 case GNUPG_Certificate_Revoked:
374                   log_error (_("the certificate has been revoked\n"));
375                   break;
376                 case GNUPG_No_CRL_Known:
377                   log_error (_("no CRL found for certificate\n"));
378                   break;
379                 case GNUPG_CRL_Too_Old:
380                   log_error (_("the available CRL is too old\n"));
381                   log_info (_("please make sure that the "
382                               "\"dirmngr\" is properly installed\n"));
383                   break;
384                 default:
385                   log_error (_("checking the CRL failed: %s\n"),
386                              gnupg_strerror (rc));
387                   break;
388                 }
389               goto leave;
390             }
391         }
392
393       if (subject && !strcmp (issuer, subject))
394         {
395           if (gpgsm_check_cert_sig (subject_cert, subject_cert) )
396             {
397               log_error ("selfsigned certificate has a BAD signatures\n");
398               rc = depth? GNUPG_Bad_Certificate_Path : GNUPG_Bad_Certificate;
399               goto leave;
400             }
401           rc = allowed_ca (subject_cert, NULL);
402           if (rc)
403             goto leave;
404
405           rc = gpgsm_agent_istrusted (subject_cert);
406           if (!rc)
407             ;
408           else if (rc == GNUPG_Not_Trusted)
409             {
410               int rc2;
411
412               char *fpr = gpgsm_get_fingerprint_string (subject_cert,
413                                                         GCRY_MD_SHA1);
414               log_info (_("root certificate is not marked trusted\n"));
415               log_info (_("fingerprint=%s\n"), fpr? fpr : "?");
416               xfree (fpr);
417               rc2 = gpgsm_agent_marktrusted (subject_cert);
418               if (!rc2)
419                 {
420                   log_info (_("root certificate has now"
421                               " been marked as trusted\n"));
422                   rc = 0;
423                 }
424               else 
425                 {
426                   gpgsm_dump_cert ("issuer", subject_cert);
427                   log_info ("after checking the fingerprint, you may want "
428                             "to enter it manually into "
429                             "\"~/.gnupg-test/trustlist.txt\"\n");
430                 }
431             }
432           else 
433             {
434               log_error (_("checking the trust list failed: %s\n"),
435                          gnupg_strerror (rc));
436             }
437           
438           break;  /* okay, a self-signed certicate is an end-point */
439         }
440       
441       depth++;
442       if (depth > maxdepth)
443         {
444           log_error (_("certificate path too long\n"));
445           rc = GNUPG_Bad_Certificate_Path;
446           goto leave;
447         }
448
449       /* find the next cert up the tree */
450       keydb_search_reset (kh);
451       rc = keydb_search_subject (kh, issuer);
452       if (rc)
453         {
454           if (rc == -1)
455             {
456               log_info ("issuer certificate (");
457               gpgsm_dump_string (issuer);
458               log_printf (") not found\n");
459             }
460           else
461             log_error ("failed to find issuer's certificate: rc=%d\n", rc);
462           rc = GNUPG_Missing_Certificate;
463           goto leave;
464         }
465
466       ksba_cert_release (issuer_cert); issuer_cert = NULL;
467       rc = keydb_get_cert (kh, &issuer_cert);
468       if (rc)
469         {
470           log_error ("failed to get cert: rc=%d\n", rc);
471           rc = GNUPG_General_Error;
472           goto leave;
473         }
474
475       if (DBG_X509)
476         {
477           log_debug ("got issuer's certificate:\n");
478           gpgsm_dump_cert ("issuer", issuer_cert);
479         }
480
481       if (gpgsm_check_cert_sig (issuer_cert, subject_cert) )
482         {
483           log_error ("certificate has a BAD signatures\n");
484           rc = GNUPG_Bad_Certificate_Path;
485           goto leave;
486         }
487
488       {
489         int pathlen;
490         rc = allowed_ca (issuer_cert, &pathlen);
491         if (rc)
492           goto leave;
493         if (pathlen >= 0 && (depth - 1) > pathlen)
494           {
495             log_error (_("certificate path longer than allowed by CA (%d)\n"),
496                        pathlen);
497             rc = GNUPG_Bad_Certificate_Path;
498             goto leave;
499           }
500       }
501
502       log_info ("certificate is good\n");
503       
504       keydb_search_reset (kh);
505       subject_cert = issuer_cert;
506       issuer_cert = NULL;
507     }
508
509   if (opt.no_policy_check)
510     log_info ("policies not checked due to --disable-policy-checks option\n");
511   if (opt.no_crl_check)
512     log_info ("CRLs not checked due to --disable-crl-checks option\n");
513   
514  leave:
515   xfree (issuer);
516   keydb_release (kh); 
517   ksba_cert_release (issuer_cert);
518   if (subject_cert != cert)
519     ksba_cert_release (subject_cert);
520   return rc;
521 }
522
523
524 /* Check that the given certificate is valid but DO NOT check any
525    constraints.  We assume that the issuers certificate is already in
526    the DB and that this one is valid; which it should be because it
527    has been checked using this function. */
528 int
529 gpgsm_basic_cert_check (KsbaCert cert)
530 {
531   int rc = 0;
532   char *issuer = NULL;
533   char *subject = NULL;
534   KEYDB_HANDLE kh = keydb_new (0);
535   KsbaCert issuer_cert = NULL;
536
537   if ((opt.debug & 4096))
538     {
539       log_info ("WARNING: bypassing basic certificate checks\n");
540       return 0;
541     }
542
543   if (!kh)
544     {
545       log_error (_("failed to allocated keyDB handle\n"));
546       rc = GNUPG_General_Error;
547       goto leave;
548     }
549
550   issuer = ksba_cert_get_issuer (cert, 0);
551   subject = ksba_cert_get_subject (cert, 0);
552   if (!issuer)
553     {
554       log_error ("no issuer found in certificate\n");
555       rc = GNUPG_Bad_Certificate;
556       goto leave;
557     }
558
559   if (subject && !strcmp (issuer, subject))
560     {
561       if (gpgsm_check_cert_sig (cert, cert) )
562         {
563           log_error ("selfsigned certificate has a BAD signatures\n");
564           rc = GNUPG_Bad_Certificate;
565           goto leave;
566         }
567     }
568   else
569     {
570       /* find the next cert up the tree */
571       keydb_search_reset (kh);
572       rc = keydb_search_subject (kh, issuer);
573       if (rc)
574         {
575           if (rc == -1)
576             {
577               log_info ("issuer certificate (");
578               gpgsm_dump_string (issuer);
579               log_printf (") not found\n");
580             }
581           else
582             log_error ("failed to find issuer's certificate: rc=%d\n", rc);
583           rc = GNUPG_Missing_Certificate;
584           goto leave;
585         }
586       
587       ksba_cert_release (issuer_cert); issuer_cert = NULL;
588       rc = keydb_get_cert (kh, &issuer_cert);
589       if (rc)
590         {
591           log_error ("failed to get cert: rc=%d\n", rc);
592           rc = GNUPG_General_Error;
593           goto leave;
594         }
595
596       if (gpgsm_check_cert_sig (issuer_cert, cert) )
597         {
598           log_error ("certificate has a BAD signatures\n");
599           rc = GNUPG_Bad_Certificate;
600           goto leave;
601         }
602       if (opt.verbose)
603         log_info ("certificate is good\n");
604     }
605
606  leave:
607   xfree (issuer);
608   keydb_release (kh); 
609   ksba_cert_release (issuer_cert);
610   return rc;
611 }
612