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