719f97b61d84e63e97d32b9187599ce17f3a70db
[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_No_Policy_Match;
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 void
200 find_up_store_certs_cb (void *cb_value, KsbaCert cert)
201 {
202   if (keydb_store_cert (cert, 1, NULL))
203     log_error ("error storing issuer certificate as ephemeral\n");
204   ++*(int*)cb_value;
205 }
206
207
208 static int
209 find_up (KEYDB_HANDLE kh, KsbaCert cert, const char *issuer)
210 {
211   KsbaName authid;
212   KsbaSexp authidno;
213   int rc = -1;
214
215   if (!ksba_cert_get_auth_key_id (cert, NULL, &authid, &authidno))
216     {
217       const char *s = ksba_name_enum (authid, 0);
218       if (s && *authidno)
219         {
220           rc = keydb_search_issuer_sn (kh, s, authidno);
221           if (rc)
222               keydb_search_reset (kh);
223           if (rc == -1)
224             { /* And try the ephemeral DB. */
225               int old = keydb_set_ephemeral (kh, 1);
226               if (!old)
227                 {
228                   rc = keydb_search_issuer_sn (kh, s, authidno);
229                   if (rc)
230                     keydb_search_reset (kh);
231                 }
232               keydb_set_ephemeral (kh, old);
233             }
234         }
235       ksba_name_release (authid);
236       xfree (authidno);
237       /* Fixme: don't know how to do dirmngr lookup with serial+issuer. */
238     }
239   
240   if (rc) /* not found via authorithyKeyIdentifier, try regular issuer name */
241       rc = keydb_search_subject (kh, issuer);
242   if (rc == -1)
243     {
244       /* Not found, lets see whether we have one in the ephemeral key DB. */
245       int old = keydb_set_ephemeral (kh, 1);
246       if (!old)
247         {
248           keydb_search_reset (kh);
249           rc = keydb_search_subject (kh, issuer);
250         }
251       keydb_set_ephemeral (kh, old);
252     }
253
254   if (rc == -1 && opt.auto_issuer_key_retrieve)
255     {
256       STRLIST names = NULL;
257       int count = 0;
258       char *pattern;
259       const char *s;
260       
261       if (opt.verbose)
262         log_info (_("looking up issuer at external location\n"));
263       /* dirmngr is confused about unknown attributes so has a quick
264          and ugly hack we locate the CN and use this and the
265          following.  Fixme: we should have far ebtter parsing in the
266          dirmngr. */
267       s = strstr (issuer, "CN=");
268       if (!s || s == issuer || s[-1] != ',')
269         s = issuer;
270
271       pattern = xtrymalloc (strlen (s)+2);
272       if (!pattern)
273         return GNUPG_Out_Of_Core;
274       strcpy (stpcpy (pattern, "/"), s);
275       add_to_strlist (&names, pattern);
276       xfree (pattern);
277       rc = gpgsm_dirmngr_lookup (NULL, names, find_up_store_certs_cb, &count);
278       free_strlist (names);
279       if (opt.verbose)
280         log_info (_("number of issuers matching: %d\n"), count);
281       if (rc) 
282         {
283           log_error ("external key lookup failed: %s\n", gnupg_strerror (rc));
284           rc = -1;
285         }
286       else if (!count)
287         rc = -1;
288       else
289         {
290           int old;
291           /* The issuers are currently stored in the ephemeral key
292              DB, so we temporary switch to ephemeral mode. */
293           old = keydb_set_ephemeral (kh, 1);
294           keydb_search_reset (kh);
295           rc = keydb_search_subject (kh, issuer);
296           keydb_set_ephemeral (kh, old);
297         }
298     }
299   return rc;
300 }
301
302
303 /* Return the next certificate up in the chain starting at START.
304    Returns -1 when there are no more certificates. */
305 int
306 gpgsm_walk_cert_chain (KsbaCert start, KsbaCert *r_next)
307 {
308   int rc = 0; 
309   char *issuer = NULL;
310   char *subject = NULL;
311   KEYDB_HANDLE kh = keydb_new (0);
312
313   *r_next = NULL;
314   if (!kh)
315     {
316       log_error (_("failed to allocated keyDB handle\n"));
317       rc = GNUPG_General_Error;
318       goto leave;
319     }
320
321   issuer = ksba_cert_get_issuer (start, 0);
322   subject = ksba_cert_get_subject (start, 0);
323   if (!issuer)
324     {
325       log_error ("no issuer found in certificate\n");
326       rc = GNUPG_Bad_Certificate;
327       goto leave;
328     }
329   if (!subject)
330     {
331       log_error ("no subject found in certificate\n");
332       rc = GNUPG_Bad_Certificate;
333       goto leave;
334     }
335
336   if (!strcmp (issuer, subject))
337     {
338       rc = -1; /* we are at the root */
339       goto leave; 
340     }
341
342   rc = find_up (kh, start, issuer);
343   if (rc)
344     {
345       /* it is quite common not to have a certificate, so better don't
346          print an error here */
347       if (rc != -1 && opt.verbose > 1)
348         log_error ("failed to find issuer's certificate: rc=%d\n", rc);
349       rc = GNUPG_Missing_Certificate;
350       goto leave;
351     }
352
353   rc = keydb_get_cert (kh, r_next);
354   if (rc)
355     {
356       log_error ("failed to get cert: rc=%d\n", rc);
357       rc = GNUPG_General_Error;
358     }
359
360  leave:
361   xfree (issuer);
362   xfree (subject);
363   keydb_release (kh); 
364   return rc;
365 }
366
367
368 /* Check whether the CERT is a root certificate.  Returns True if this
369    is the case. */
370 int
371 gpgsm_is_root_cert (KsbaCert cert)
372 {
373   char *issuer;
374   char *subject;
375   int yes;
376
377   issuer = ksba_cert_get_issuer (cert, 0);
378   subject = ksba_cert_get_subject (cert, 0);
379   yes = (issuer && subject && !strcmp (issuer, subject));
380   xfree (issuer);
381   xfree (subject);
382   return yes;
383 }
384
385 \f
386 /* Validate a path and optionally return the nearest expiration time
387    in R_EXPTIME */
388 int
389 gpgsm_validate_path (CTRL ctrl, KsbaCert cert, time_t *r_exptime)
390 {
391   int rc = 0, depth = 0, maxdepth;
392   char *issuer = NULL;
393   char *subject = NULL;
394   KEYDB_HANDLE kh = keydb_new (0);
395   KsbaCert subject_cert = NULL, issuer_cert = NULL;
396   time_t current_time = gnupg_get_time ();
397   time_t exptime = 0;
398   int any_expired = 0;
399   int any_revoked = 0;
400   int any_no_crl = 0;
401   int any_crl_too_old = 0;
402   int any_no_policy_match = 0;
403
404   if (r_exptime)
405     *r_exptime = 0;
406
407   if (opt.no_path_validation)
408     {
409       log_info ("WARNING: bypassing path validation\n");
410       return 0;
411     }
412   
413   if (!kh)
414     {
415       log_error (_("failed to allocated keyDB handle\n"));
416       rc = GNUPG_General_Error;
417       goto leave;
418     }
419
420   if (DBG_X509)
421     gpgsm_dump_cert ("subject", cert);
422
423   subject_cert = cert;
424   maxdepth = 50;
425
426   for (;;)
427     {
428       xfree (issuer);
429       xfree (subject);
430       issuer = ksba_cert_get_issuer (subject_cert, 0);
431       subject = ksba_cert_get_subject (subject_cert, 0);
432
433       if (!issuer)
434         {
435           log_error ("no issuer found in certificate\n");
436           rc = GNUPG_Bad_Certificate;
437           goto leave;
438         }
439
440       {
441         time_t not_before, not_after;
442
443         not_before = ksba_cert_get_validity (subject_cert, 0);
444         not_after = ksba_cert_get_validity (subject_cert, 1);
445         if (not_before == (time_t)(-1) || not_after == (time_t)(-1))
446           {
447             log_error ("certificate with invalid validity\n");
448             rc = GNUPG_Bad_Certificate;
449             goto leave;
450           }
451
452         if (not_after)
453           {
454             if (!exptime)
455               exptime = not_after;
456             else if (not_after < exptime)
457               exptime = not_after;
458           }
459
460         if (not_before && current_time < not_before)
461           {
462             log_error ("certificate too young; valid from ");
463             gpgsm_dump_time (not_before);
464             log_printf ("\n");
465             rc = GNUPG_Certificate_Too_Young;
466             goto leave;
467           }            
468         if (not_after && current_time > not_after)
469           {
470             log_error ("certificate has expired at ");
471             gpgsm_dump_time (not_after);
472             log_printf ("\n");
473             any_expired = 1;
474           }            
475       }
476
477       rc = unknown_criticals (subject_cert);
478       if (rc)
479         goto leave;
480
481       if (!opt.no_policy_check)
482         {
483           rc = check_cert_policy (subject_cert);
484           if (rc == GNUPG_No_Policy_Match)
485             {
486               any_no_policy_match = 1;
487               rc = 1;
488             }
489           else if (rc)
490             goto leave;
491         }
492
493       if (!opt.no_crl_check)
494         {
495           rc = gpgsm_dirmngr_isvalid (subject_cert);
496           if (rc)
497             {
498               switch (rc)
499                 {
500                 case GNUPG_Certificate_Revoked:
501                   log_error (_("the certificate has been revoked\n"));
502                   any_revoked = 1;
503                   break;
504                 case GNUPG_No_CRL_Known:
505                   log_error (_("no CRL found for certificate\n"));
506                   any_no_crl = 1;
507                   break;
508                 case GNUPG_CRL_Too_Old:
509                   log_error (_("the available CRL is too old\n"));
510                   log_info (_("please make sure that the "
511                               "\"dirmngr\" is properly installed\n"));
512                   any_crl_too_old = 1;
513                   break;
514                 default:
515                   log_error (_("checking the CRL failed: %s\n"),
516                              gnupg_strerror (rc));
517                   goto leave;
518                 }
519               rc = 0;
520             }
521         }
522
523       if (subject && !strcmp (issuer, subject))
524         {
525           if (gpgsm_check_cert_sig (subject_cert, subject_cert) )
526             {
527               log_error ("selfsigned certificate has a BAD signatures\n");
528               rc = depth? GNUPG_Bad_Certificate_Path : GNUPG_Bad_Certificate;
529               goto leave;
530             }
531           rc = allowed_ca (subject_cert, NULL);
532           if (rc)
533             goto leave;
534
535           rc = gpgsm_agent_istrusted (subject_cert);
536           if (!rc)
537             ;
538           else if (rc == GNUPG_Not_Trusted)
539             {
540               int rc2;
541
542               char *fpr = gpgsm_get_fingerprint_string (subject_cert,
543                                                         GCRY_MD_SHA1);
544               log_info (_("root certificate is not marked trusted\n"));
545               log_info (_("fingerprint=%s\n"), fpr? fpr : "?");
546               xfree (fpr);
547               rc2 = gpgsm_agent_marktrusted (subject_cert);
548               if (!rc2)
549                 {
550                   log_info (_("root certificate has now"
551                               " been marked as trusted\n"));
552                   rc = 0;
553                 }
554               else 
555                 {
556                   gpgsm_dump_cert ("issuer", subject_cert);
557                   log_info ("after checking the fingerprint, you may want "
558                             "to enter it manually into "
559                             "\"~/.gnupg-test/trustlist.txt\"\n");
560                 }
561             }
562           else 
563             {
564               log_error (_("checking the trust list failed: %s\n"),
565                          gnupg_strerror (rc));
566             }
567           
568           break;  /* okay, a self-signed certicate is an end-point */
569         }
570       
571       depth++;
572       if (depth > maxdepth)
573         {
574           log_error (_("certificate path too long\n"));
575           rc = GNUPG_Bad_Certificate_Path;
576           goto leave;
577         }
578
579       /* find the next cert up the tree */
580       keydb_search_reset (kh);
581       rc = find_up (kh, subject_cert, issuer);
582       if (rc)
583         {
584           if (rc == -1)
585             {
586               log_info ("issuer certificate (");
587               gpgsm_dump_string (issuer);
588               log_printf (") not found\n");
589             }
590           else
591             log_error ("failed to find issuer's certificate: rc=%d\n", rc);
592           rc = GNUPG_Missing_Certificate;
593           goto leave;
594         }
595
596       ksba_cert_release (issuer_cert); issuer_cert = NULL;
597       rc = keydb_get_cert (kh, &issuer_cert);
598       if (rc)
599         {
600           log_error ("failed to get cert: rc=%d\n", rc);
601           rc = GNUPG_General_Error;
602           goto leave;
603         }
604
605       if (DBG_X509)
606         {
607           log_debug ("got issuer's certificate:\n");
608           gpgsm_dump_cert ("issuer", issuer_cert);
609         }
610
611       if (gpgsm_check_cert_sig (issuer_cert, subject_cert) )
612         {
613           log_error ("certificate has a BAD signatures\n");
614           rc = GNUPG_Bad_Certificate_Path;
615           goto leave;
616         }
617
618       {
619         int pathlen;
620         rc = allowed_ca (issuer_cert, &pathlen);
621         if (rc)
622           goto leave;
623         if (pathlen >= 0 && (depth - 1) > pathlen)
624           {
625             log_error (_("certificate path longer than allowed by CA (%d)\n"),
626                        pathlen);
627             rc = GNUPG_Bad_Certificate_Path;
628             goto leave;
629           }
630       }
631
632       rc = gpgsm_cert_use_cert_p (issuer_cert);
633       if (rc)
634         {
635           gpgsm_status2 (ctrl, STATUS_ERROR, "certpath.issuer.keyusage",
636                          gnupg_error_token (rc), NULL);
637           rc = 0;
638         }
639
640       if (opt.verbose)
641         log_info ("certificate is good\n");
642       
643       keydb_search_reset (kh);
644       subject_cert = issuer_cert;
645       issuer_cert = NULL;
646     }
647
648   if (opt.no_policy_check)
649     log_info ("policies not checked due to --disable-policy-checks option\n");
650   if (opt.no_crl_check)
651     log_info ("CRLs not checked due to --disable-crl-checks option\n");
652
653   if (!rc)
654     { /* If we encountered an error somewhere during the checks, set
655          the error code to the most critical one */
656       if (any_revoked)
657         rc = GNUPG_Certificate_Revoked;
658       else if (any_no_crl)
659         rc = GNUPG_No_CRL_Known;
660       else if (any_crl_too_old)
661         rc = GNUPG_CRL_Too_Old;
662       else if (any_no_policy_match)
663         rc = GNUPG_No_Policy_Match;
664       else if (any_expired)
665         rc = GNUPG_Certificate_Expired;
666     }
667   
668  leave:
669   if (r_exptime)
670     *r_exptime = exptime;
671   xfree (issuer);
672   keydb_release (kh); 
673   ksba_cert_release (issuer_cert);
674   if (subject_cert != cert)
675     ksba_cert_release (subject_cert);
676   return rc;
677 }
678
679
680 /* Check that the given certificate is valid but DO NOT check any
681    constraints.  We assume that the issuers certificate is already in
682    the DB and that this one is valid; which it should be because it
683    has been checked using this function. */
684 int
685 gpgsm_basic_cert_check (KsbaCert cert)
686 {
687   int rc = 0;
688   char *issuer = NULL;
689   char *subject = NULL;
690   KEYDB_HANDLE kh = keydb_new (0);
691   KsbaCert issuer_cert = NULL;
692
693   if (opt.no_path_validation)
694     {
695       log_info ("WARNING: bypassing basic certificate checks\n");
696       return 0;
697     }
698
699   if (!kh)
700     {
701       log_error (_("failed to allocated keyDB handle\n"));
702       rc = GNUPG_General_Error;
703       goto leave;
704     }
705
706   issuer = ksba_cert_get_issuer (cert, 0);
707   subject = ksba_cert_get_subject (cert, 0);
708   if (!issuer)
709     {
710       log_error ("no issuer found in certificate\n");
711       rc = GNUPG_Bad_Certificate;
712       goto leave;
713     }
714
715   if (subject && !strcmp (issuer, subject))
716     {
717       if (gpgsm_check_cert_sig (cert, cert) )
718         {
719           log_error ("selfsigned certificate has a BAD signatures\n");
720           rc = GNUPG_Bad_Certificate;
721           goto leave;
722         }
723     }
724   else
725     {
726       /* find the next cert up the tree */
727       keydb_search_reset (kh);
728       rc = find_up (kh, cert, issuer);
729       if (rc)
730         {
731           if (rc == -1)
732             {
733               log_info ("issuer certificate (");
734               gpgsm_dump_string (issuer);
735               log_printf (") not found\n");
736             }
737           else
738             log_error ("failed to find issuer's certificate: rc=%d\n", rc);
739           rc = GNUPG_Missing_Certificate;
740           goto leave;
741         }
742       
743       ksba_cert_release (issuer_cert); issuer_cert = NULL;
744       rc = keydb_get_cert (kh, &issuer_cert);
745       if (rc)
746         {
747           log_error ("failed to get cert: rc=%d\n", rc);
748           rc = GNUPG_General_Error;
749           goto leave;
750         }
751
752       if (gpgsm_check_cert_sig (issuer_cert, cert) )
753         {
754           log_error ("certificate has a BAD signatures\n");
755           rc = GNUPG_Bad_Certificate;
756           goto leave;
757         }
758       if (opt.verbose)
759         log_info ("certificate is good\n");
760     }
761
762  leave:
763   xfree (issuer);
764   keydb_release (kh); 
765   ksba_cert_release (issuer_cert);
766   return rc;
767 }
768