1283ce46dc5a49a3337d62c06e9dbf7e95f11a7c
[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
199 static int
200 find_up (KEYDB_HANDLE kh, KsbaCert cert, const char *issuer)
201 {
202   KsbaName authid;
203   KsbaSexp authidno;
204   int rc = -1;
205
206   if (!ksba_cert_get_auth_key_id (cert, NULL, &authid, &authidno))
207     {
208       const char *s = ksba_name_enum (authid, 0);
209       if (s && *authidno)
210         {
211           rc = keydb_search_issuer_sn (kh, s, authidno);
212           if (rc)
213               keydb_search_reset (kh);
214         }
215       ksba_name_release (authid);
216       xfree (authidno);
217     }
218   
219   if (rc)
220     rc = keydb_search_subject (kh, issuer);
221   return rc;
222 }
223
224
225 /* Return the next certificate up in the chain starting at START.
226    Returns -1 when there are no more certificates. */
227 int
228 gpgsm_walk_cert_chain (KsbaCert start, KsbaCert *r_next)
229 {
230   int rc = 0; 
231   char *issuer = NULL;
232   char *subject = NULL;
233   KEYDB_HANDLE kh = keydb_new (0);
234
235   *r_next = NULL;
236   if (!kh)
237     {
238       log_error (_("failed to allocated keyDB handle\n"));
239       rc = GNUPG_General_Error;
240       goto leave;
241     }
242
243   issuer = ksba_cert_get_issuer (start, 0);
244   subject = ksba_cert_get_subject (start, 0);
245   if (!issuer)
246     {
247       log_error ("no issuer found in certificate\n");
248       rc = GNUPG_Bad_Certificate;
249       goto leave;
250     }
251   if (!subject)
252     {
253       log_error ("no subject found in certificate\n");
254       rc = GNUPG_Bad_Certificate;
255       goto leave;
256     }
257
258   if (!strcmp (issuer, subject))
259     {
260       rc = -1; /* we are at the root */
261       goto leave; 
262     }
263
264   rc = find_up (kh, start, issuer);
265   if (rc)
266     {
267       /* it is quite common not to have a certificate, so better don't
268          print an error here */
269       if (rc != -1 && opt.verbose > 1)
270         log_error ("failed to find issuer's certificate: rc=%d\n", rc);
271       rc = GNUPG_Missing_Certificate;
272       goto leave;
273     }
274
275   rc = keydb_get_cert (kh, r_next);
276   if (rc)
277     {
278       log_error ("failed to get cert: rc=%d\n", rc);
279       rc = GNUPG_General_Error;
280     }
281
282  leave:
283   xfree (issuer);
284   xfree (subject);
285   keydb_release (kh); 
286   return rc;
287 }
288
289
290 /* Check whether the CERT is a root certificate.  Returns True if this
291    is the case. */
292 int
293 gpgsm_is_root_cert (KsbaCert cert)
294 {
295   char *issuer;
296   char *subject;
297   int yes;
298
299   issuer = ksba_cert_get_issuer (cert, 0);
300   subject = ksba_cert_get_subject (cert, 0);
301   yes = (issuer && subject && !strcmp (issuer, subject));
302   xfree (issuer);
303   xfree (subject);
304   return yes;
305 }
306
307 \f
308 /* Validate a path and optionally return the nearest expiration time
309    in R_EXPTIME */
310 int
311 gpgsm_validate_path (KsbaCert cert, time_t *r_exptime)
312 {
313   int rc = 0, depth = 0, maxdepth;
314   char *issuer = NULL;
315   char *subject = NULL;
316   KEYDB_HANDLE kh = keydb_new (0);
317   KsbaCert subject_cert = NULL, issuer_cert = NULL;
318   time_t current_time = time (NULL);
319   time_t exptime = 0;
320
321   if (r_exptime)
322     *r_exptime = 0;
323
324   if ((opt.debug & 4096))
325     {
326       log_info ("WARNING: bypassing path validation\n");
327       return 0;
328     }
329   
330   if (!kh)
331     {
332       log_error (_("failed to allocated keyDB handle\n"));
333       rc = GNUPG_General_Error;
334       goto leave;
335     }
336
337   if (DBG_X509)
338     gpgsm_dump_cert ("subject", cert);
339
340   subject_cert = cert;
341   maxdepth = 50;
342
343   for (;;)
344     {
345       xfree (issuer);
346       xfree (subject);
347       issuer = ksba_cert_get_issuer (subject_cert, 0);
348       subject = ksba_cert_get_subject (subject_cert, 0);
349
350       if (!issuer)
351         {
352           log_error ("no issuer found in certificate\n");
353           rc = GNUPG_Bad_Certificate;
354           goto leave;
355         }
356
357       {
358         time_t not_before, not_after;
359
360         not_before = ksba_cert_get_validity (subject_cert, 0);
361         not_after = ksba_cert_get_validity (subject_cert, 1);
362         if (not_before == (time_t)(-1) || not_after == (time_t)(-1))
363           {
364             log_error ("certificate with invalid validity\n");
365             rc = GNUPG_Bad_Certificate;
366             goto leave;
367           }
368
369         if (not_after)
370           {
371             if (!exptime)
372               exptime = not_after;
373             else if (not_after < exptime)
374               exptime = not_after;
375           }
376
377         if (not_before && current_time < not_before)
378           {
379             log_error ("certificate to young; valid from ");
380             gpgsm_dump_time (not_before);
381             log_printf ("\n");
382             rc = GNUPG_Certificate_Too_Young;
383             goto leave;
384           }            
385         if (not_after && current_time > not_after)
386           {
387             log_error ("certificate has expired at ");
388             gpgsm_dump_time (not_after);
389             log_printf ("\n");
390             rc = GNUPG_Certificate_Expired;
391             goto leave;
392           }            
393       }
394
395       rc = unknown_criticals (subject_cert);
396       if (rc)
397         goto leave;
398
399       if (!opt.no_policy_check)
400         {
401           rc = check_cert_policy (subject_cert);
402           if (rc)
403             goto leave;
404         }
405
406       if (!opt.no_crl_check)
407         {
408           rc = gpgsm_dirmngr_isvalid (subject_cert);
409           if (rc)
410             {
411               switch (rc)
412                 {
413                 case GNUPG_Certificate_Revoked:
414                   log_error (_("the certificate has been revoked\n"));
415                   break;
416                 case GNUPG_No_CRL_Known:
417                   log_error (_("no CRL found for certificate\n"));
418                   break;
419                 case GNUPG_CRL_Too_Old:
420                   log_error (_("the available CRL is too old\n"));
421                   log_info (_("please make sure that the "
422                               "\"dirmngr\" is properly installed\n"));
423                   break;
424                 default:
425                   log_error (_("checking the CRL failed: %s\n"),
426                              gnupg_strerror (rc));
427                   break;
428                 }
429               goto leave;
430             }
431         }
432
433       if (subject && !strcmp (issuer, subject))
434         {
435           if (gpgsm_check_cert_sig (subject_cert, subject_cert) )
436             {
437               log_error ("selfsigned certificate has a BAD signatures\n");
438               rc = depth? GNUPG_Bad_Certificate_Path : GNUPG_Bad_Certificate;
439               goto leave;
440             }
441           rc = allowed_ca (subject_cert, NULL);
442           if (rc)
443             goto leave;
444
445           rc = gpgsm_agent_istrusted (subject_cert);
446           if (!rc)
447             ;
448           else if (rc == GNUPG_Not_Trusted)
449             {
450               int rc2;
451
452               char *fpr = gpgsm_get_fingerprint_string (subject_cert,
453                                                         GCRY_MD_SHA1);
454               log_info (_("root certificate is not marked trusted\n"));
455               log_info (_("fingerprint=%s\n"), fpr? fpr : "?");
456               xfree (fpr);
457               rc2 = gpgsm_agent_marktrusted (subject_cert);
458               if (!rc2)
459                 {
460                   log_info (_("root certificate has now"
461                               " been marked as trusted\n"));
462                   rc = 0;
463                 }
464               else 
465                 {
466                   gpgsm_dump_cert ("issuer", subject_cert);
467                   log_info ("after checking the fingerprint, you may want "
468                             "to enter it manually into "
469                             "\"~/.gnupg-test/trustlist.txt\"\n");
470                 }
471             }
472           else 
473             {
474               log_error (_("checking the trust list failed: %s\n"),
475                          gnupg_strerror (rc));
476             }
477           
478           break;  /* okay, a self-signed certicate is an end-point */
479         }
480       
481       depth++;
482       if (depth > maxdepth)
483         {
484           log_error (_("certificate path too long\n"));
485           rc = GNUPG_Bad_Certificate_Path;
486           goto leave;
487         }
488
489       /* find the next cert up the tree */
490       keydb_search_reset (kh);
491       rc = find_up (kh, subject_cert, issuer);
492       if (rc)
493         {
494           if (rc == -1)
495             {
496               log_info ("issuer certificate (");
497               gpgsm_dump_string (issuer);
498               log_printf (") not found\n");
499             }
500           else
501             log_error ("failed to find issuer's certificate: rc=%d\n", rc);
502           rc = GNUPG_Missing_Certificate;
503           goto leave;
504         }
505
506       ksba_cert_release (issuer_cert); issuer_cert = NULL;
507       rc = keydb_get_cert (kh, &issuer_cert);
508       if (rc)
509         {
510           log_error ("failed to get cert: rc=%d\n", rc);
511           rc = GNUPG_General_Error;
512           goto leave;
513         }
514
515       if (DBG_X509)
516         {
517           log_debug ("got issuer's certificate:\n");
518           gpgsm_dump_cert ("issuer", issuer_cert);
519         }
520
521       if (gpgsm_check_cert_sig (issuer_cert, subject_cert) )
522         {
523           log_error ("certificate has a BAD signatures\n");
524           rc = GNUPG_Bad_Certificate_Path;
525           goto leave;
526         }
527
528       {
529         int pathlen;
530         rc = allowed_ca (issuer_cert, &pathlen);
531         if (rc)
532           goto leave;
533         if (pathlen >= 0 && (depth - 1) > pathlen)
534           {
535             log_error (_("certificate path longer than allowed by CA (%d)\n"),
536                        pathlen);
537             rc = GNUPG_Bad_Certificate_Path;
538             goto leave;
539           }
540       }
541
542       if (opt.verbose)
543         log_info ("certificate is good\n");
544       
545       keydb_search_reset (kh);
546       subject_cert = issuer_cert;
547       issuer_cert = NULL;
548     }
549
550   if (opt.no_policy_check)
551     log_info ("policies not checked due to --disable-policy-checks option\n");
552   if (opt.no_crl_check)
553     log_info ("CRLs not checked due to --disable-crl-checks option\n");
554   
555  leave:
556   if (r_exptime)
557     *r_exptime = exptime;
558   xfree (issuer);
559   keydb_release (kh); 
560   ksba_cert_release (issuer_cert);
561   if (subject_cert != cert)
562     ksba_cert_release (subject_cert);
563   return rc;
564 }
565
566
567 /* Check that the given certificate is valid but DO NOT check any
568    constraints.  We assume that the issuers certificate is already in
569    the DB and that this one is valid; which it should be because it
570    has been checked using this function. */
571 int
572 gpgsm_basic_cert_check (KsbaCert cert)
573 {
574   int rc = 0;
575   char *issuer = NULL;
576   char *subject = NULL;
577   KEYDB_HANDLE kh = keydb_new (0);
578   KsbaCert issuer_cert = NULL;
579
580   if ((opt.debug & 4096))
581     {
582       log_info ("WARNING: bypassing basic certificate checks\n");
583       return 0;
584     }
585
586   if (!kh)
587     {
588       log_error (_("failed to allocated keyDB handle\n"));
589       rc = GNUPG_General_Error;
590       goto leave;
591     }
592
593   issuer = ksba_cert_get_issuer (cert, 0);
594   subject = ksba_cert_get_subject (cert, 0);
595   if (!issuer)
596     {
597       log_error ("no issuer found in certificate\n");
598       rc = GNUPG_Bad_Certificate;
599       goto leave;
600     }
601
602   if (subject && !strcmp (issuer, subject))
603     {
604       if (gpgsm_check_cert_sig (cert, cert) )
605         {
606           log_error ("selfsigned certificate has a BAD signatures\n");
607           rc = GNUPG_Bad_Certificate;
608           goto leave;
609         }
610     }
611   else
612     {
613       /* find the next cert up the tree */
614       keydb_search_reset (kh);
615       rc = find_up (kh, cert, issuer);
616       if (rc)
617         {
618           if (rc == -1)
619             {
620               log_info ("issuer certificate (");
621               gpgsm_dump_string (issuer);
622               log_printf (") not found\n");
623             }
624           else
625             log_error ("failed to find issuer's certificate: rc=%d\n", rc);
626           rc = GNUPG_Missing_Certificate;
627           goto leave;
628         }
629       
630       ksba_cert_release (issuer_cert); issuer_cert = NULL;
631       rc = keydb_get_cert (kh, &issuer_cert);
632       if (rc)
633         {
634           log_error ("failed to get cert: rc=%d\n", rc);
635           rc = GNUPG_General_Error;
636           goto leave;
637         }
638
639       if (gpgsm_check_cert_sig (issuer_cert, cert) )
640         {
641           log_error ("certificate has a BAD signatures\n");
642           rc = GNUPG_Bad_Certificate;
643           goto leave;
644         }
645       if (opt.verbose)
646         log_info ("certificate is good\n");
647     }
648
649  leave:
650   xfree (issuer);
651   keydb_release (kh); 
652   ksba_cert_release (issuer_cert);
653   return rc;
654 }
655