* certcheck.c: Fixed use of DBG_CRYPTO and DBG_X509.
[gnupg.git] / sm / certchain.c
1 /* certchain.c - certificate chain validation
2  * Copyright (C) 2001, 2002, 2003, 2004, 2005 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 <stdarg.h>
29 #include <assert.h>
30
31 #define JNLIB_NEED_LOG_LOGV /* We need log_logv. */
32
33 #include "gpgsm.h"
34 #include <gcrypt.h>
35 #include <ksba.h>
36
37 #include "keydb.h"
38 #include "../kbx/keybox.h" /* for KEYBOX_FLAG_* */
39 #include "i18n.h"
40
41
42 /* If LISTMODE is true, print FORMAT using LISTMODE to FP.  If
43    LISTMODE is false, use the string to print an log_info or, if
44    IS_ERROR is true, and log_error. */
45 static void
46 do_list (int is_error, int listmode, FILE *fp, const char *format, ...)
47 {
48   va_list arg_ptr;
49
50   va_start (arg_ptr, format) ;
51   if (listmode)
52     {
53       if (fp)
54         {
55           fputs ("  [", fp);
56           vfprintf (fp, format, arg_ptr);
57           fputs ("]\n", fp);
58         }
59     }
60   else
61     {
62       log_logv (is_error? JNLIB_LOG_ERROR: JNLIB_LOG_INFO, format, arg_ptr);
63       log_printf ("\n");
64     }
65   va_end (arg_ptr);
66 }
67
68 /* Return 0 if A and B are equal. */
69 static int
70 compare_certs (ksba_cert_t a, ksba_cert_t b)
71 {
72   const unsigned char *img_a, *img_b;
73   size_t len_a, len_b;
74
75   img_a = ksba_cert_get_image (a, &len_a);
76   if (!img_a)
77     return 1;
78   img_b = ksba_cert_get_image (b, &len_b);
79   if (!img_b)
80     return 1;
81   return !(len_a == len_b && !memcmp (img_a, img_b, len_a));
82 }
83
84
85 static int
86 unknown_criticals (ksba_cert_t cert, int listmode, FILE *fp)
87 {
88   static const char *known[] = {
89     "2.5.29.15", /* keyUsage */
90     "2.5.29.19", /* basic Constraints */
91     "2.5.29.32", /* certificatePolicies */
92     "2.5.29.37", /* extendedKeyUsage - handled by certlist.c */
93     NULL
94   };
95   int rc = 0, i, idx, crit;
96   const char *oid;
97   gpg_error_t err;
98
99   for (idx=0; !(err=ksba_cert_get_extension (cert, idx,
100                                              &oid, &crit, NULL, NULL));idx++)
101     {
102       if (!crit)
103         continue;
104       for (i=0; known[i] && strcmp (known[i],oid); i++)
105         ;
106       if (!known[i])
107         {
108           do_list (1, listmode, fp,
109                    _("critical certificate extension %s is not supported"),
110                    oid);
111           rc = gpg_error (GPG_ERR_UNSUPPORTED_CERT);
112         }
113     }
114   if (err && gpg_err_code (err) != GPG_ERR_EOF)
115     rc = err;
116
117   return rc;
118 }
119
120 static int
121 allowed_ca (ksba_cert_t cert, int *chainlen, int listmode, FILE *fp)
122 {
123   gpg_error_t err;
124   int flag;
125
126   err = ksba_cert_is_ca (cert, &flag, chainlen);
127   if (err)
128     return err;
129   if (!flag)
130     {
131       do_list (1, listmode, fp,_("issuer certificate is not marked as a CA"));
132       return gpg_error (GPG_ERR_BAD_CA_CERT);
133     }
134   return 0;
135 }
136
137
138 static int
139 check_cert_policy (ksba_cert_t cert, int listmode, FILE *fplist)
140 {
141   gpg_error_t err;
142   char *policies;
143   FILE *fp;
144   int any_critical;
145
146   err = ksba_cert_get_cert_policies (cert, &policies);
147   if (gpg_err_code (err) == GPG_ERR_NO_DATA)
148     return 0; /* no policy given */
149   if (err)
150     return err;
151
152   /* STRING is a line delimited list of certifiate policies as stored
153      in the certificate.  The line itself is colon delimited where the
154      first field is the OID of the policy and the second field either
155      N or C for normal or critical extension */
156
157   if (opt.verbose > 1 && !listmode)
158     log_info ("certificate's policy list: %s\n", policies);
159
160   /* The check is very minimal but won't give false positives */
161   any_critical = !!strstr (policies, ":C");
162
163   if (!opt.policy_file)
164     { 
165       xfree (policies);
166       if (any_critical)
167         {
168           do_list (1, listmode, fplist,
169                    _("critical marked policy without configured policies"));
170           return gpg_error (GPG_ERR_NO_POLICY_MATCH);
171         }
172       return 0;
173     }
174
175   fp = fopen (opt.policy_file, "r");
176   if (!fp)
177     {
178       log_error ("failed to open `%s': %s\n",
179                  opt.policy_file, strerror (errno));
180       xfree (policies);
181       /* With no critical policies this is only a warning */
182       if (!any_critical)
183         {
184           do_list (0, listmode, fplist,
185                    _("note: non-critical certificate policy not allowed"));
186           return 0;
187         }
188       do_list (1, listmode, fplist,
189                _("certificate policy not allowed"));
190       return gpg_error (GPG_ERR_NO_POLICY_MATCH);
191     }
192
193   for (;;) 
194     {
195       int c;
196       char *p, line[256];
197       char *haystack, *allowed;
198
199       /* read line */
200       do
201         {
202           if (!fgets (line, DIM(line)-1, fp) )
203             {
204               gpg_error_t tmperr = gpg_error (gpg_err_code_from_errno (errno));
205
206               xfree (policies);
207               if (feof (fp))
208                 {
209                   fclose (fp);
210                   /* With no critical policies this is only a warning */
211                   if (!any_critical)
212                     {
213                       do_list (0, listmode, fplist,
214                      _("note: non-critical certificate policy not allowed"));
215                       return 0;
216                     }
217                   do_list (1, listmode, fplist,
218                            _("certificate policy not allowed"));
219                   return gpg_error (GPG_ERR_NO_POLICY_MATCH);
220                 }
221               fclose (fp);
222               return tmperr;
223             }
224       
225           if (!*line || line[strlen(line)-1] != '\n')
226             {
227               /* eat until end of line */
228               while ( (c=getc (fp)) != EOF && c != '\n')
229                 ;
230               fclose (fp);
231               xfree (policies);
232               return gpg_error (*line? GPG_ERR_LINE_TOO_LONG
233                                      : GPG_ERR_INCOMPLETE_LINE);
234             }
235           
236           /* Allow for empty lines and spaces */
237           for (p=line; spacep (p); p++)
238             ;
239         }
240       while (!*p || *p == '\n' || *p == '#');
241   
242       /* parse line */
243       for (allowed=line; spacep (allowed); allowed++)
244         ;
245       p = strpbrk (allowed, " :\n");
246       if (!*p || p == allowed)
247         {
248           fclose (fp);
249           xfree (policies);
250           return gpg_error (GPG_ERR_CONFIGURATION);
251         }
252       *p = 0; /* strip the rest of the line */
253       /* See whether we find ALLOWED (which is an OID) in POLICIES */
254       for (haystack=policies; (p=strstr (haystack, allowed)); haystack = p+1)
255         {
256           if ( !(p == policies || p[-1] == '\n') )
257             continue; /* Does not match the begin of a line. */
258           if (p[strlen (allowed)] != ':')
259             continue; /* The length does not match. */
260           /* Yep - it does match so return okay. */
261           fclose (fp);
262           xfree (policies);
263           return 0;
264         }
265     }
266 }
267
268
269 static void
270 find_up_store_certs_cb (void *cb_value, ksba_cert_t cert)
271 {
272   if (keydb_store_cert (cert, 1, NULL))
273     log_error ("error storing issuer certificate as ephemeral\n");
274   ++*(int*)cb_value;
275 }
276
277
278
279 /* Helper for find_up().  Locate the certificate for ISSUER using an
280    external lookup.  KH is the keydb context we are currently using.
281    On success 0 is returned and the certificate may be retrieved from
282    the keydb using keydb_get_cert().*/
283 static int
284 find_up_external (KEYDB_HANDLE kh, const char *issuer)
285 {
286   int rc;
287   strlist_t names = NULL;
288   int count = 0;
289   char *pattern;
290   const char *s;
291       
292   if (opt.verbose)
293     log_info (_("looking up issuer at external location\n"));
294   /* The DIRMNGR process is confused about unknown attributes.  As a
295      quick and ugly hack we locate the CN and use the issuer string
296      starting at this attribite.  Fixme: we should have far better
297      parsing in the dirmngr. */
298   s = strstr (issuer, "CN=");
299   if (!s || s == issuer || s[-1] != ',')
300     s = issuer;
301
302   pattern = xtrymalloc (strlen (s)+2);
303   if (!pattern)
304     return gpg_error_from_errno (errno);
305   strcpy (stpcpy (pattern, "/"), s);
306   add_to_strlist (&names, pattern);
307   xfree (pattern);
308
309   rc = gpgsm_dirmngr_lookup (NULL, names, find_up_store_certs_cb, &count);
310   free_strlist (names);
311
312   if (opt.verbose)
313     log_info (_("number of issuers matching: %d\n"), count);
314   if (rc) 
315     {
316       log_error ("external key lookup failed: %s\n", gpg_strerror (rc));
317       rc = -1;
318     }
319   else if (!count)
320     rc = -1;
321   else
322     {
323       int old;
324       /* The issuers are currently stored in the ephemeral key DB, so
325          we temporary switch to ephemeral mode. */
326       old = keydb_set_ephemeral (kh, 1);
327       keydb_search_reset (kh);
328       rc = keydb_search_subject (kh, issuer);
329       keydb_set_ephemeral (kh, old);
330     }
331   return rc;
332 }
333
334
335 /* Locate issuing certificate for CERT. ISSUER is the name of the
336    issuer used as a fallback if the other methods don't work.  If
337    FIND_NEXT is true, the function shall return the next possible
338    issuer.  The certificate itself is not directly returned but a
339    keydb_get_cert on the keyDb context KH will return it.  Returns 0
340    on success, -1 if not found or an error code.  */
341 static int
342 find_up (KEYDB_HANDLE kh, ksba_cert_t cert, const char *issuer, int find_next)
343 {
344   ksba_name_t authid;
345   ksba_sexp_t authidno;
346   int rc = -1;
347
348   if (!ksba_cert_get_auth_key_id (cert, NULL, &authid, &authidno))
349     {
350       const char *s = ksba_name_enum (authid, 0);
351       if (s && *authidno)
352         {
353           rc = keydb_search_issuer_sn (kh, s, authidno);
354           if (rc)
355               keydb_search_reset (kh);
356           
357           /* In case of an error try the ephemeral DB.  We can't do
358              that in find_next mode because we can't keep the search
359              state then. */
360           if (rc == -1 && !find_next)
361             { 
362               int old = keydb_set_ephemeral (kh, 1);
363               if (!old)
364                 {
365                   rc = keydb_search_issuer_sn (kh, s, authidno);
366                   if (rc)
367                     keydb_search_reset (kh);
368                 }
369               keydb_set_ephemeral (kh, old);
370             }
371
372           /* If we didn't found it, try an external lookup.  */
373           if (rc == -1 && opt.auto_issuer_key_retrieve && !find_next)
374             rc = find_up_external (kh, issuer);
375         }
376
377       /* Print a note so that the user does not feel too helpless when
378          an issuer certificate was found and gpgsm prints BAD
379          signature because it is not the correct one. */
380       if (rc == -1)
381         {
382           log_info ("%sissuer certificate (#", find_next?"next ":"");
383           gpgsm_dump_serial (authidno);
384           log_printf ("/");
385           gpgsm_dump_string (s);
386           log_printf (") not found using authorityKeyIdentifier\n");
387         }
388       else if (rc)
389         log_error ("failed to find authorityKeyIdentifier: rc=%d\n", rc);
390       ksba_name_release (authid);
391       xfree (authidno);
392       /* Fixme: There is no way to do an external lookup with
393          serial+issuer. */
394     }
395   
396   if (rc) /* Not found via authorithyKeyIdentifier, try regular issuer name. */
397     rc = keydb_search_subject (kh, issuer);
398   if (rc == -1 && !find_next)
399     {
400       /* Not found, lets see whether we have one in the ephemeral key DB. */
401       int old = keydb_set_ephemeral (kh, 1);
402       if (!old)
403         {
404           keydb_search_reset (kh);
405           rc = keydb_search_subject (kh, issuer);
406         }
407       keydb_set_ephemeral (kh, old);
408     }
409
410   /* Still not found.  If enabled, try an external lookup.  */
411   if (rc == -1 && opt.auto_issuer_key_retrieve && !find_next)
412     rc = find_up_external (kh, issuer);
413
414   return rc;
415 }
416
417
418 /* Return the next certificate up in the chain starting at START.
419    Returns -1 when there are no more certificates. */
420 int
421 gpgsm_walk_cert_chain (ksba_cert_t start, ksba_cert_t *r_next)
422 {
423   int rc = 0; 
424   char *issuer = NULL;
425   char *subject = NULL;
426   KEYDB_HANDLE kh = keydb_new (0);
427
428   *r_next = NULL;
429   if (!kh)
430     {
431       log_error (_("failed to allocated keyDB handle\n"));
432       rc = gpg_error (GPG_ERR_GENERAL);
433       goto leave;
434     }
435
436   issuer = ksba_cert_get_issuer (start, 0);
437   subject = ksba_cert_get_subject (start, 0);
438   if (!issuer)
439     {
440       log_error ("no issuer found in certificate\n");
441       rc = gpg_error (GPG_ERR_BAD_CERT);
442       goto leave;
443     }
444   if (!subject)
445     {
446       log_error ("no subject found in certificate\n");
447       rc = gpg_error (GPG_ERR_BAD_CERT);
448       goto leave;
449     }
450
451   if (!strcmp (issuer, subject))
452     {
453       rc = -1; /* we are at the root */
454       goto leave; 
455     }
456
457   rc = find_up (kh, start, issuer, 0);
458   if (rc)
459     {
460       /* it is quite common not to have a certificate, so better don't
461          print an error here */
462       if (rc != -1 && opt.verbose > 1)
463         log_error ("failed to find issuer's certificate: rc=%d\n", rc);
464       rc = gpg_error (GPG_ERR_MISSING_CERT);
465       goto leave;
466     }
467
468   rc = keydb_get_cert (kh, r_next);
469   if (rc)
470     {
471       log_error ("failed to get cert: rc=%d\n", rc);
472       rc = gpg_error (GPG_ERR_GENERAL);
473     }
474
475  leave:
476   xfree (issuer);
477   xfree (subject);
478   keydb_release (kh); 
479   return rc;
480 }
481
482
483 /* Check whether the CERT is a root certificate.  Returns True if this
484    is the case. */
485 int
486 gpgsm_is_root_cert (ksba_cert_t cert)
487 {
488   char *issuer;
489   char *subject;
490   int yes;
491
492   issuer = ksba_cert_get_issuer (cert, 0);
493   subject = ksba_cert_get_subject (cert, 0);
494   yes = (issuer && subject && !strcmp (issuer, subject));
495   xfree (issuer);
496   xfree (subject);
497   return yes;
498 }
499
500
501 /* This is a helper for gpgsm_validate_chain. */
502 static gpg_error_t 
503 is_cert_still_valid (ctrl_t ctrl, int lm, FILE *fp,
504                      ksba_cert_t subject_cert, ksba_cert_t issuer_cert,
505                      int *any_revoked, int *any_no_crl, int *any_crl_too_old)
506 {
507   if (!opt.no_crl_check || ctrl->use_ocsp)
508     {
509       gpg_error_t err;
510
511       err = gpgsm_dirmngr_isvalid (ctrl,
512                                    subject_cert, issuer_cert, ctrl->use_ocsp);
513       if (err)
514         {
515           /* Fixme: We should change the wording because we may
516              have used OCSP. */
517           switch (gpg_err_code (err))
518             {
519             case GPG_ERR_CERT_REVOKED:
520               do_list (1, lm, fp, _("certificate has been revoked"));
521               *any_revoked = 1;
522               /* Store that in the keybox so that key listings are
523                  able to return the revoked flag.  We don't care
524                  about error, though. */
525               keydb_set_cert_flags (subject_cert, KEYBOX_FLAG_VALIDITY, 0,
526                                     VALIDITY_REVOKED);
527               break;
528             case GPG_ERR_NO_CRL_KNOWN:
529               do_list (1, lm, fp, _("no CRL found for certificate"));
530               *any_no_crl = 1;
531               break;
532             case GPG_ERR_CRL_TOO_OLD:
533               do_list (1, lm, fp, _("the available CRL is too old"));
534               if (!lm)
535                 log_info (_("please make sure that the "
536                             "\"dirmngr\" is properly installed\n"));
537               *any_crl_too_old = 1;
538               break;
539             default:
540               do_list (1, lm, fp, _("checking the CRL failed: %s"),
541                        gpg_strerror (err));
542               return err;
543             }
544         }
545     }
546   return 0;
547 }
548
549
550 \f
551 /* Validate a chain and optionally return the nearest expiration time
552    in R_EXPTIME. With LISTMODE set to 1 a special listmode is
553    activated where only information about the certificate is printed
554    to FP and no output is send to the usual log stream. 
555
556    Defined flag bits: 0 - do not do any dirmngr isvalid checks.
557 */
558 int
559 gpgsm_validate_chain (ctrl_t ctrl, ksba_cert_t cert, ksba_isotime_t r_exptime,
560                       int listmode, FILE *fp, unsigned int flags)
561 {
562   int rc = 0, depth = 0, maxdepth;
563   char *issuer = NULL;
564   char *subject = NULL;
565   KEYDB_HANDLE kh = NULL;
566   ksba_cert_t subject_cert = NULL, issuer_cert = NULL;
567   ksba_isotime_t current_time;
568   ksba_isotime_t exptime;
569   int any_expired = 0;
570   int any_revoked = 0;
571   int any_no_crl = 0;
572   int any_crl_too_old = 0;
573   int any_no_policy_match = 0;
574   int lm = listmode;
575
576   gnupg_get_isotime (current_time);
577   if (r_exptime)
578     *r_exptime = 0;
579   *exptime = 0;
580
581   if (opt.no_chain_validation && !listmode)
582     {
583       log_info ("WARNING: bypassing certificate chain validation\n");
584       return 0;
585     }
586
587   kh = keydb_new (0);
588   if (!kh)
589     {
590       log_error (_("failed to allocated keyDB handle\n"));
591       rc = gpg_error (GPG_ERR_GENERAL);
592       goto leave;
593     }
594
595   if (DBG_X509 && !listmode)
596     gpgsm_dump_cert ("target", cert);
597
598   subject_cert = cert;
599   maxdepth = 50;
600
601   for (;;)
602     {
603       xfree (issuer);
604       xfree (subject);
605       issuer = ksba_cert_get_issuer (subject_cert, 0);
606       subject = ksba_cert_get_subject (subject_cert, 0);
607
608       if (!issuer)
609         {
610           do_list (1, lm, fp,  _("no issuer found in certificate"));
611           rc = gpg_error (GPG_ERR_BAD_CERT);
612           goto leave;
613         }
614
615       {
616         ksba_isotime_t not_before, not_after;
617
618         rc = ksba_cert_get_validity (subject_cert, 0, not_before);
619         if (!rc)
620           rc = ksba_cert_get_validity (subject_cert, 1, not_after);
621         if (rc)
622           {
623             do_list (1, lm, fp, _("certificate with invalid validity: %s"),
624                      gpg_strerror (rc));
625             rc = gpg_error (GPG_ERR_BAD_CERT);
626             goto leave;
627           }
628
629         if (*not_after)
630           {
631             if (!*exptime)
632               gnupg_copy_time (exptime, not_after);
633             else if (strcmp (not_after, exptime) < 0 )
634               gnupg_copy_time (exptime, not_after);
635           }
636
637         if (*not_before && strcmp (current_time, not_before) < 0 )
638           {
639             do_list (1, lm, fp, _("certificate not yet valid"));
640             if (!lm)
641               {
642                 log_info ("(valid from ");
643                 gpgsm_dump_time (not_before);
644                 log_printf (")\n");
645               }
646             rc = gpg_error (GPG_ERR_CERT_TOO_YOUNG);
647             goto leave;
648           }            
649         if (*not_after && strcmp (current_time, not_after) > 0 )
650           {
651             do_list (opt.ignore_expiration?0:1, lm, fp,
652                      _("certificate has expired"));
653             if (!lm)
654               {
655                 log_info ("(expired at ");
656                 gpgsm_dump_time (not_after);
657                 log_printf (")\n");
658               }
659             if (opt.ignore_expiration)
660                 log_info ("WARNING: ignoring expiration\n");
661             else
662               any_expired = 1;
663           }            
664       }
665
666       rc = unknown_criticals (subject_cert, listmode, fp);
667       if (rc)
668         goto leave;
669
670       if (!opt.no_policy_check)
671         {
672           rc = check_cert_policy (subject_cert, listmode, fp);
673           if (gpg_err_code (rc) == GPG_ERR_NO_POLICY_MATCH)
674             {
675               any_no_policy_match = 1;
676               rc = 1;
677             }
678           else if (rc)
679             goto leave;
680         }
681
682
683       /* Is this a self-signed certificate? */
684       if (subject && !strcmp (issuer, subject))
685         {  /* Yes. */
686           if (gpgsm_check_cert_sig (subject_cert, subject_cert) )
687             {
688               do_list (1, lm, fp,
689                        _("selfsigned certificate has a BAD signature"));
690               if (DBG_X509)
691                 {
692                   gpgsm_dump_cert ("self-signing cert", subject_cert);
693                 }
694               rc = gpg_error (depth? GPG_ERR_BAD_CERT_CHAIN
695                                    : GPG_ERR_BAD_CERT);
696               goto leave;
697             }
698           rc = allowed_ca (subject_cert, NULL, listmode, fp);
699           if (rc)
700             goto leave;
701
702           rc = gpgsm_agent_istrusted (ctrl, subject_cert);
703           if (!rc)
704             ;
705           else if (gpg_err_code (rc) == GPG_ERR_NOT_TRUSTED)
706             {
707               do_list (0, lm, fp, _("root certificate is not marked trusted"));
708               /* If we already figured out that the certificate is
709                  expired it does not make much sense to ask the user
710                  whether we wants to trust the root certificate.  He
711                  should do this only if the certificate under question
712                  will then be usable. */
713               if (!lm && !any_expired)
714                 {
715                   int rc2;
716                   char *fpr = gpgsm_get_fingerprint_string (subject_cert,
717                                                             GCRY_MD_SHA1);
718                   log_info (_("fingerprint=%s\n"), fpr? fpr : "?");
719                   xfree (fpr);
720                   rc2 = gpgsm_agent_marktrusted (ctrl, subject_cert);
721                   if (!rc2)
722                     {
723                       log_info (_("root certificate has now"
724                                   " been marked as trusted\n"));
725                       rc = 0;
726                     }
727                   else 
728                     {
729                       gpgsm_dump_cert ("issuer", subject_cert);
730                       log_info ("after checking the fingerprint, you may want "
731                                 "to add it manually to the list of trusted "
732                                 "certificates.\n");
733                     }
734                 }
735             }
736           else 
737             {
738               log_error (_("checking the trust list failed: %s\n"),
739                          gpg_strerror (rc));
740             }
741           
742           if (rc)
743             goto leave;
744
745           /* Check for revocations etc. */
746           if ((flags & 1))
747             rc = 0;
748           else if (any_expired)
749             ; /* Don't bother to run the expensive CRL check then. */
750           else
751             rc = is_cert_still_valid (ctrl, lm, fp,
752                                       subject_cert, subject_cert,
753                                       &any_revoked, &any_no_crl,
754                                       &any_crl_too_old);
755           if (rc)
756             goto leave;
757
758           break;  /* Okay: a self-signed certicate is an end-point. */
759         }
760       
761       depth++;
762       if (depth > maxdepth)
763         {
764           do_list (1, lm, fp, _("certificate chain too long\n"));
765           rc = gpg_error (GPG_ERR_BAD_CERT_CHAIN);
766           goto leave;
767         }
768
769       /* find the next cert up the tree */
770       keydb_search_reset (kh);
771       rc = find_up (kh, subject_cert, issuer, 0);
772       if (rc)
773         {
774           if (rc == -1)
775             {
776               do_list (0, lm, fp, _("issuer certificate not found"));
777               if (!lm)
778                 {
779                   log_info ("issuer certificate: #/");
780                   gpgsm_dump_string (issuer);
781                   log_printf ("\n");
782                 }
783             }
784           else
785             log_error ("failed to find issuer's certificate: rc=%d\n", rc);
786           rc = gpg_error (GPG_ERR_MISSING_CERT);
787           goto leave;
788         }
789
790       ksba_cert_release (issuer_cert); issuer_cert = NULL;
791       rc = keydb_get_cert (kh, &issuer_cert);
792       if (rc)
793         {
794           log_error ("failed to get cert: rc=%d\n", rc);
795           rc = gpg_error (GPG_ERR_GENERAL);
796           goto leave;
797         }
798
799     try_another_cert:
800       if (DBG_X509)
801         {
802           log_debug ("got issuer's certificate:\n");
803           gpgsm_dump_cert ("issuer", issuer_cert);
804         }
805
806       rc = gpgsm_check_cert_sig (issuer_cert, subject_cert);
807       if (rc)
808         {
809           do_list (0, lm, fp, _("certificate has a BAD signature"));
810           if (DBG_X509)
811             {
812               gpgsm_dump_cert ("signing issuer", issuer_cert);
813               gpgsm_dump_cert ("signed subject", subject_cert);
814             }
815           if (gpg_err_code (rc) == GPG_ERR_BAD_SIGNATURE)
816             {
817               /* We now try to find other issuer certificates which
818                  might have been used.  This is required because some
819                  CAs are reusing the issuer and subject DN for new
820                  root certificates. */
821               rc = find_up (kh, subject_cert, issuer, 1);
822               if (!rc)
823                 {
824                   ksba_cert_t tmp_cert;
825
826                   rc = keydb_get_cert (kh, &tmp_cert);
827                   if (rc || !compare_certs (issuer_cert, tmp_cert))
828                     {
829                       /* The find next did not work or returned an
830                          identical certificate.  We better stop here
831                          to avoid infinite checks. */
832                       rc = gpg_error (GPG_ERR_BAD_SIGNATURE);
833                       ksba_cert_release (tmp_cert);
834                     }
835                   else
836                     {
837                       do_list (0, lm, fp, _("found another possible matching "
838                                             "CA certificate - trying again"));
839                       ksba_cert_release (issuer_cert); 
840                       issuer_cert = tmp_cert;
841                       goto try_another_cert;
842                     }
843                 }
844             }
845
846           /* We give a more descriptive error code than the one
847              returned from the signature checking. */
848           rc = gpg_error (GPG_ERR_BAD_CERT_CHAIN);
849           goto leave;
850         }
851
852       {
853         int chainlen;
854         rc = allowed_ca (issuer_cert, &chainlen, listmode, fp);
855         if (rc)
856           goto leave;
857         if (chainlen >= 0 && (depth - 1) > chainlen)
858           {
859             do_list (1, lm, fp,
860                      _("certificate chain longer than allowed by CA (%d)"),
861                      chainlen);
862             rc = gpg_error (GPG_ERR_BAD_CERT_CHAIN);
863             goto leave;
864           }
865       }
866
867       if (!listmode)
868         {
869           rc = gpgsm_cert_use_cert_p (issuer_cert);
870           if (rc)
871             {
872               char numbuf[50];
873               sprintf (numbuf, "%d", rc);
874               gpgsm_status2 (ctrl, STATUS_ERROR, "certcert.issuer.keyusage",
875                              numbuf, NULL);
876               goto leave;
877             }
878         }
879
880       /* Check for revocations etc. */
881       if ((flags & 1))
882         rc = 0;
883       else if (any_expired)
884         ; /* Don't bother to run the expensive CRL check then. */
885       else
886         rc = is_cert_still_valid (ctrl, lm, fp,
887                                   subject_cert, issuer_cert,
888                                   &any_revoked, &any_no_crl, &any_crl_too_old);
889       if (rc)
890         goto leave;
891
892
893       if (opt.verbose && !listmode)
894         log_info ("certificate is good\n");
895       
896       keydb_search_reset (kh);
897       subject_cert = issuer_cert;
898       issuer_cert = NULL;
899     }
900
901   if (!listmode)
902     {
903       if (opt.no_policy_check)
904         log_info ("policies not checked due to %s option\n",
905                   "--disable-policy-checks");
906       if (opt.no_crl_check && !ctrl->use_ocsp)
907         log_info ("CRLs not checked due to %s option\n",
908                   "--disable-crl-checks");
909     }
910
911   if (!rc)
912     { /* If we encountered an error somewhere during the checks, set
913          the error code to the most critical one */
914       if (any_revoked)
915         rc = gpg_error (GPG_ERR_CERT_REVOKED);
916       else if (any_expired)
917         rc = gpg_error (GPG_ERR_CERT_EXPIRED);
918       else if (any_no_crl)
919         rc = gpg_error (GPG_ERR_NO_CRL_KNOWN);
920       else if (any_crl_too_old)
921         rc = gpg_error (GPG_ERR_CRL_TOO_OLD);
922       else if (any_no_policy_match)
923         rc = gpg_error (GPG_ERR_NO_POLICY_MATCH);
924     }
925   
926  leave:
927   if (r_exptime)
928     gnupg_copy_time (r_exptime, exptime);
929   xfree (issuer);
930   keydb_release (kh); 
931   ksba_cert_release (issuer_cert);
932   if (subject_cert != cert)
933     ksba_cert_release (subject_cert);
934   return rc;
935 }
936
937
938 /* Check that the given certificate is valid but DO NOT check any
939    constraints.  We assume that the issuers certificate is already in
940    the DB and that this one is valid; which it should be because it
941    has been checked using this function. */
942 int
943 gpgsm_basic_cert_check (ksba_cert_t cert)
944 {
945   int rc = 0;
946   char *issuer = NULL;
947   char *subject = NULL;
948   KEYDB_HANDLE kh = keydb_new (0);
949   ksba_cert_t issuer_cert = NULL;
950   
951   if (opt.no_chain_validation)
952     {
953       log_info ("WARNING: bypassing basic certificate checks\n");
954       return 0;
955     }
956
957   if (!kh)
958     {
959       log_error (_("failed to allocated keyDB handle\n"));
960       rc = gpg_error (GPG_ERR_GENERAL);
961       goto leave;
962     }
963
964   issuer = ksba_cert_get_issuer (cert, 0);
965   subject = ksba_cert_get_subject (cert, 0);
966   if (!issuer)
967     {
968       log_error ("no issuer found in certificate\n");
969       rc = gpg_error (GPG_ERR_BAD_CERT);
970       goto leave;
971     }
972
973   if (subject && !strcmp (issuer, subject))
974     {
975       rc = gpgsm_check_cert_sig (cert, cert);
976       if (rc)
977         {
978           log_error ("selfsigned certificate has a BAD signature: %s\n",
979                      gpg_strerror (rc));
980           if (DBG_X509)
981             {
982               gpgsm_dump_cert ("self-signing cert", cert);
983             }
984           rc = gpg_error (GPG_ERR_BAD_CERT);
985           goto leave;
986         }
987     }
988   else
989     {
990       /* Find the next cert up the tree. */
991       keydb_search_reset (kh);
992       rc = find_up (kh, cert, issuer, 0);
993       if (rc)
994         {
995           if (rc == -1)
996             {
997               log_info ("issuer certificate (#/");
998               gpgsm_dump_string (issuer);
999               log_printf (") not found\n");
1000             }
1001           else
1002             log_error ("failed to find issuer's certificate: rc=%d\n", rc);
1003           rc = gpg_error (GPG_ERR_MISSING_CERT);
1004           goto leave;
1005         }
1006       
1007       ksba_cert_release (issuer_cert); issuer_cert = NULL;
1008       rc = keydb_get_cert (kh, &issuer_cert);
1009       if (rc)
1010         {
1011           log_error ("failed to get cert: rc=%d\n", rc);
1012           rc = gpg_error (GPG_ERR_GENERAL);
1013           goto leave;
1014         }
1015
1016       rc = gpgsm_check_cert_sig (issuer_cert, cert);
1017       if (rc)
1018         {
1019           log_error ("certificate has a BAD signature: %s\n",
1020                      gpg_strerror (rc));
1021           if (DBG_X509)
1022             {
1023               gpgsm_dump_cert ("signing issuer", issuer_cert);
1024               gpgsm_dump_cert ("signed subject", cert);
1025             }
1026           rc = gpg_error (GPG_ERR_BAD_CERT);
1027           goto leave;
1028         }
1029       if (opt.verbose)
1030         log_info ("certificate is good\n");
1031     }
1032
1033  leave:
1034   xfree (issuer);
1035   keydb_release (kh); 
1036   ksba_cert_release (issuer_cert);
1037   return rc;
1038 }
1039