* certpath.c (check_cert_policy): New.
[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 delimted 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   /* The check is very minimal but won't give false positives */
108   any_critical = !!strstr (policies, ":C");
109
110   if (!opt.policy_file)
111     { 
112       xfree (policies);
113       if (any_critical)
114         {
115           log_error ("critical marked policy without configured policies\n");
116           return GNUPG_No_Policy_Match;
117         }
118       return 0;
119     }
120
121   fp = fopen (opt.policy_file, "r");
122   if (!fp)
123     {
124       log_error ("failed to open `%s': %s\n",
125                  opt.policy_file, strerror (errno));
126       xfree (policies);
127       return GNUPG_Configuration_Error;
128     }
129
130   for (;;) 
131     {
132       int c;
133       char *p, line[256];
134       char *haystack, *allowed;
135
136       /* read line */
137       do
138         {
139           if (!fgets (line, DIM(line)-1, fp) )
140             {
141               xfree (policies);
142               if (feof (fp))
143                 {
144                   fclose (fp);
145                   log_error (_("certificate policy not allowed\n"));
146                   /* with no critical policies this is only a warning */
147                   return any_critical? GNUPG_No_Policy_Match : 0;
148                 }
149               fclose (fp);
150               return GNUPG_Read_Error;
151             }
152       
153           if (!*line || line[strlen(line)-1] != '\n')
154             {
155               /* eat until end of line */
156               while ( (c=getc (fp)) != EOF && c != '\n')
157                 ;
158               fclose (fp);
159               xfree (policies);
160               return *line? GNUPG_Line_Too_Long: GNUPG_Incomplete_Line;
161             }
162           
163           /* Allow for empty lines and spaces */
164           for (p=line; spacep (p); p++)
165             ;
166         }
167       while (!*p || *p == '\n' || *p == '#');
168   
169       /* parse line */
170       for (allowed=line; spacep (allowed); allowed++)
171         ;
172       p = strpbrk (allowed, " :\n");
173       if (!*p || p == allowed)
174         {
175           fclose (fp);
176           xfree (policies);
177           return GNUPG_Configuration_Error;
178         }
179       *p = 0; /* strip the rest of the line */
180       /* See whether we find ALLOWED (which is an OID) in POLICIES */
181       for (haystack=policies; (p=strstr (haystack, allowed)); haystack = p+1)
182         {
183           if ( !(p == policies || p[-1] == '\n') )
184             continue; /* does not match the begin of a line */
185           if (p[strlen (allowed)] != ':')
186             continue; /* the length does not match */
187           /* Yep - it does match so return okay */
188           fclose (fp);
189           xfree (policies);
190           return 0;
191         }
192     }
193 }
194
195 /* Return the next certificate up in the chain starting at START.
196    Returns -1 when there are no more certificates. */
197 int
198 gpgsm_walk_cert_chain (KsbaCert start, KsbaCert *r_next)
199 {
200   int rc = 0; 
201   char *issuer = NULL;
202   char *subject = NULL;
203   KEYDB_HANDLE kh = keydb_new (0);
204
205   *r_next = NULL;
206   if (!kh)
207     {
208       log_error (_("failed to allocated keyDB handle\n"));
209       rc = GNUPG_General_Error;
210       goto leave;
211     }
212
213   issuer = ksba_cert_get_issuer (start, 0);
214   subject = ksba_cert_get_subject (start, 0);
215   if (!issuer)
216     {
217       log_error ("no issuer found in certificate\n");
218       rc = GNUPG_Bad_Certificate;
219       goto leave;
220     }
221   if (!subject)
222     {
223       log_error ("no subject found in certificate\n");
224       rc = GNUPG_Bad_Certificate;
225       goto leave;
226     }
227
228   if (!strcmp (issuer, subject))
229     {
230       rc = -1; /* we are at the root */
231       goto leave; 
232     }
233  
234   rc = keydb_search_subject (kh, issuer);
235   if (rc)
236     {
237       log_error ("failed to find issuer's certificate: rc=%d\n", rc);
238       rc = GNUPG_Missing_Certificate;
239       goto leave;
240     }
241
242   rc = keydb_get_cert (kh, r_next);
243   if (rc)
244     {
245       log_error ("failed to get cert: rc=%d\n", rc);
246       rc = GNUPG_General_Error;
247     }
248
249  leave:
250   xfree (issuer);
251   xfree (subject);
252   keydb_release (kh); 
253   return rc;
254 }
255
256 \f
257 int
258 gpgsm_validate_path (KsbaCert cert)
259 {
260   int rc = 0, depth = 0, maxdepth;
261   char *issuer = NULL;
262   char *subject = NULL;
263   KEYDB_HANDLE kh = keydb_new (0);
264   KsbaCert subject_cert = NULL, issuer_cert = NULL;
265   time_t current_time = time (NULL);
266
267   if (!kh)
268     {
269       log_error (_("failed to allocated keyDB handle\n"));
270       rc = GNUPG_General_Error;
271       goto leave;
272     }
273
274   if (DBG_X509)
275     gpgsm_dump_cert ("subject", cert);
276
277   subject_cert = cert;
278   maxdepth = 50;
279
280   for (;;)
281     {
282       xfree (issuer);
283       xfree (subject);
284       issuer = ksba_cert_get_issuer (subject_cert, 0);
285       subject = ksba_cert_get_subject (subject_cert, 0);
286
287       if (!issuer)
288         {
289           log_error ("no issuer found in certificate\n");
290           rc = GNUPG_Bad_Certificate;
291           goto leave;
292         }
293
294       {
295         time_t not_before, not_after;
296
297         not_before = ksba_cert_get_validity (subject_cert, 0);
298         not_after = ksba_cert_get_validity (subject_cert, 1);
299         if (not_before == (time_t)(-1) || not_after == (time_t)(-1))
300           {
301             log_error ("certificate with invalid validity\n");
302             rc = GNUPG_Bad_Certificate;
303             goto leave;
304           }
305
306         if (current_time < not_before)
307           {
308             log_error ("certificate to young; valid from ");
309             gpgsm_dump_time (not_before);
310             log_printf ("\n");
311             rc = GNUPG_Certificate_Too_Young;
312             goto leave;
313           }            
314         if (current_time > not_after)
315           {
316             log_error ("certificate has expired at ");
317             gpgsm_dump_time (not_after);
318             log_printf ("\n");
319             rc = GNUPG_Certificate_Expired;
320             goto leave;
321           }            
322       }
323
324       rc = unknown_criticals (subject_cert);
325       if (rc)
326         goto leave;
327
328       if (!opt.no_policy_check)
329         {
330           rc = check_cert_policy (subject_cert);
331           if (rc)
332             goto leave;
333         }
334
335       if (!opt.no_crl_check)
336         {
337           rc = gpgsm_dirmngr_isvalid (subject_cert);
338           if (rc)
339             {
340               switch (rc)
341                 {
342                 case GNUPG_Certificate_Revoked:
343                   log_error (_("the certificate has been revoked\n"));
344                   break;
345                 case GNUPG_No_CRL_Known:
346                   log_error (_("no CRL found for certificate\n"));
347                   break;
348                 case GNUPG_CRL_Too_Old:
349                   log_error (_("the available CRL is too old\n"));
350                   log_info (_("please make sure that the "
351                               "\"dirmngr\" is properly installed\n"));
352                   break;
353                 default:
354                   log_error (_("checking the CRL failed: %s\n"),
355                              gnupg_strerror (rc));
356                   break;
357                 }
358               goto leave;
359             }
360         }
361
362       if (subject && !strcmp (issuer, subject))
363         {
364           if (gpgsm_check_cert_sig (subject_cert, subject_cert) )
365             {
366               log_error ("selfsigned certificate has a BAD signatures\n");
367               rc = depth? GNUPG_Bad_Certificate_Path : GNUPG_Bad_Certificate;
368               goto leave;
369             }
370           rc = allowed_ca (subject_cert, NULL);
371           if (rc)
372             goto leave;
373
374           rc = gpgsm_agent_istrusted (subject_cert);
375           if (!rc)
376             ;
377           else if (rc == GNUPG_Not_Trusted)
378             {
379               int rc2;
380
381               char *fpr = gpgsm_get_fingerprint_string (subject_cert,
382                                                         GCRY_MD_SHA1);
383               log_info (_("root certificate is not marked trusted\n"));
384               log_info (_("fingerprint=%s\n"), fpr? fpr : "?");
385               xfree (fpr);
386               rc2 = gpgsm_agent_marktrusted (subject_cert);
387               if (!rc2)
388                 {
389                   log_info (_("root certificate has now"
390                               " been marked as trusted\n"));
391                   rc = 0;
392                 }
393               else 
394                 {
395                   gpgsm_dump_cert ("issuer", subject_cert);
396                   log_info ("after checking the fingerprint, you may want "
397                             "to enter it manually into "
398                             "\"~/.gnupg-test/trustlist.txt\"\n");
399                 }
400             }
401           else 
402             {
403               log_error (_("checking the trust list failed: %s\n"),
404                          gnupg_strerror (rc));
405             }
406           
407           break;  /* okay, a self-signed certicate is an end-point */
408         }
409       
410       depth++;
411       if (depth > maxdepth)
412         {
413           log_error (_("certificate path too long\n"));
414           rc = GNUPG_Bad_Certificate_Path;
415           goto leave;
416         }
417
418       /* find the next cert up the tree */
419       keydb_search_reset (kh);
420       rc = keydb_search_subject (kh, issuer);
421       if (rc)
422         {
423           if (rc == -1)
424             {
425               log_info ("issuer certificate (");
426               gpgsm_dump_string (issuer);
427               log_printf (") not found\n");
428             }
429           else
430             log_error ("failed to find issuer's certificate: rc=%d\n", rc);
431           rc = GNUPG_Missing_Certificate;
432           goto leave;
433         }
434
435       ksba_cert_release (issuer_cert); issuer_cert = NULL;
436       rc = keydb_get_cert (kh, &issuer_cert);
437       if (rc)
438         {
439           log_error ("failed to get cert: rc=%d\n", rc);
440           rc = GNUPG_General_Error;
441           goto leave;
442         }
443
444       if (DBG_X509)
445         {
446           log_debug ("got issuer's certificate:\n");
447           gpgsm_dump_cert ("issuer", issuer_cert);
448         }
449
450       if (gpgsm_check_cert_sig (issuer_cert, subject_cert) )
451         {
452           log_error ("certificate has a BAD signatures\n");
453           rc = GNUPG_Bad_Certificate_Path;
454           goto leave;
455         }
456
457       {
458         int pathlen;
459         rc = allowed_ca (issuer_cert, &pathlen);
460         if (rc)
461           goto leave;
462         if (pathlen >= 0 && (depth - 1) > pathlen)
463           {
464             log_error (_("certificate path longer than allowed by CA (%d)\n"),
465                        pathlen);
466             rc = GNUPG_Bad_Certificate_Path;
467             goto leave;
468           }
469       }
470
471       log_info ("certificate is good\n");
472       
473       keydb_search_reset (kh);
474       subject_cert = issuer_cert;
475       issuer_cert = NULL;
476     }
477
478   if (opt.no_policy_check)
479     log_info ("policies not checked due to --disable-policy-checks option\n");
480   if (opt.no_crl_check)
481     log_info ("CRLs not checked due to --disable-crl-checks option\n");
482   
483  leave:
484   xfree (issuer);
485   keydb_release (kh); 
486   ksba_cert_release (issuer_cert);
487   if (subject_cert != cert)
488     ksba_cert_release (subject_cert);
489   return rc;
490 }
491
492
493 /* Check that the given certificate is valid but DO NOT check any
494    constraints.  We assume that the issuers certificate is already in
495    the DB and that this one is valid; which it should be because it
496    has been checked using this function. */
497 int
498 gpgsm_basic_cert_check (KsbaCert cert)
499 {
500   int rc = 0;
501   char *issuer = NULL;
502   char *subject = NULL;
503   KEYDB_HANDLE kh = keydb_new (0);
504   KsbaCert issuer_cert = NULL;
505
506   if (!kh)
507     {
508       log_error (_("failed to allocated keyDB handle\n"));
509       rc = GNUPG_General_Error;
510       goto leave;
511     }
512
513   issuer = ksba_cert_get_issuer (cert, 0);
514   subject = ksba_cert_get_subject (cert, 0);
515   if (!issuer)
516     {
517       if (DBG_X509)
518         log_debug ("ERROR: issuer missing\n");
519       rc = GNUPG_Bad_Certificate;
520       goto leave;
521     }
522
523   if (subject && !strcmp (issuer, subject))
524     {
525       if (gpgsm_check_cert_sig (cert, cert) )
526         {
527           log_error ("selfsigned certificate has a BAD signatures\n");
528           rc = GNUPG_Bad_Certificate;
529           goto leave;
530         }
531     }
532   else
533     {
534       /* find the next cert up the tree */
535       keydb_search_reset (kh);
536       rc = keydb_search_subject (kh, issuer);
537       if (rc)
538         {
539           if (rc == -1)
540             {
541               log_info ("issuer certificate (");
542               gpgsm_dump_string (issuer);
543               log_printf (") not found\n");
544             }
545           else
546             log_error ("failed to find issuer's certificate: rc=%d\n", rc);
547           rc = GNUPG_Missing_Certificate;
548           goto leave;
549         }
550       
551       ksba_cert_release (issuer_cert); issuer_cert = NULL;
552       rc = keydb_get_cert (kh, &issuer_cert);
553       if (rc)
554         {
555           log_error ("failed to get cert: rc=%d\n", rc);
556           rc = GNUPG_General_Error;
557           goto leave;
558         }
559
560       if (gpgsm_check_cert_sig (issuer_cert, cert) )
561         {
562           log_error ("certificate has a BAD signatures\n");
563           rc = GNUPG_Bad_Certificate;
564           goto leave;
565         }
566       if (opt.verbose)
567         log_info ("certificate is good\n");
568     }
569
570  leave:
571   xfree (issuer);
572   keydb_release (kh); 
573   ksba_cert_release (issuer_cert);
574   return rc;
575 }
576