LCOV - code coverage report
Current view: top level - dirmngr - crlcache.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 1224 0.0 %
Date: 2016-09-12 12:29:17 Functions: 0 35 0.0 %

          Line data    Source code
       1             : /* crlcache.c - LDAP access
       2             :  * Copyright (C) 2002 Klarälvdalens Datakonsult AB
       3             :  * Copyright (C) 2003, 2004, 2005, 2008 g10 Code GmbH
       4             :  *
       5             :  * This file is part of DirMngr.
       6             :  *
       7             :  * DirMngr is free software; you can redistribute it and/or modify
       8             :  * it under the terms of the GNU General Public License as published by
       9             :  * the Free Software Foundation; either version 2 of the License, or
      10             :  * (at your option) any later version.
      11             :  *
      12             :  * DirMngr is distributed in the hope that it will be useful,
      13             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :  * GNU General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU General Public License
      18             :  * along with this program; if not, see <http://www.gnu.org/licenses/>.
      19             :  */
      20             : 
      21             : /*
      22             : 
      23             :    1. To keep track of the CRLs actually cached and to store the meta
      24             :       information of the CRLs a simple record oriented text file is
      25             :       used.  Fields in the file are colon (':') separated and values
      26             :       containing colons or linefeeds are percent escaped (e.g. a colon
      27             :       itself is represented as "%3A").
      28             : 
      29             :       The first field is a record type identifier, so that the file is
      30             :       useful to keep track of other meta data too.
      31             : 
      32             :       The name of the file is "DIR.txt".
      33             : 
      34             : 
      35             :    1.1. Comment record
      36             : 
      37             :         Field 1: Constant beginning with "#".
      38             : 
      39             :         Other fields are not defined and such a record is simply
      40             :         skipped during processing.
      41             : 
      42             :    1.2. Version record
      43             : 
      44             :         Field 1: Constant "v"
      45             :         Field 2: Version number of this file.  Must be 1.
      46             : 
      47             :         This record must be the first non-comment record record and
      48             :         there shall only exist one record of this type.
      49             : 
      50             :    1.3. CRL cache record
      51             : 
      52             :         Field 1: Constant "c", "u" or "i".
      53             :                  A "c" or "u" indicate a valid cache entry, however
      54             :                  "u" requires that a user root certificate check needs
      55             :                  to be done.
      56             :                  An "i" indicates an invalid cache entry which should
      57             :                  not be used but still exists so that it can be
      58             :                  updated at NEXT_UPDATE.
      59             :         Field 2: Hexadecimal encoded SHA-1 hash of the issuer DN using
      60             :                  uppercase letters.
      61             :         Field 3: Issuer DN in RFC-2253 notation.
      62             :         Field 4: URL used to retrieve the corresponding CRL.
      63             :         Field 5: 15 character ISO timestamp with THIS_UPDATE.
      64             :         Field 6: 15 character ISO timestamp with NEXT_UPDATE.
      65             :         Field 7: Hexadecimal encoded MD-5 hash of the DB file to detect
      66             :                  accidental modified (i.e. deleted and created) cache files.
      67             :         Field 8: optional CRL number as a hex string.
      68             :         Field 9:  AuthorityKeyID.issuer, each Name separated by 0x01
      69             :         Field 10: AuthorityKeyID.serial
      70             :         Field 11: Hex fingerprint of trust anchor if field 1 is 'u'.
      71             : 
      72             :    2. Layout of the standard CRL Cache DB file:
      73             : 
      74             :       We use records of variable length with this structure
      75             : 
      76             :       n  bytes  Serialnumber (binary) used as key
      77             :                 thus there is no need to store the length explicitly with DB2.
      78             :       1  byte   Reason for revocation
      79             :                 (currently the KSBA reason flags are used)
      80             :       15 bytes  ISO date of revocation (e.g. 19980815T142000)
      81             :                 Note that there is no terminating 0 stored.
      82             : 
      83             :       The filename used is the hexadecimal (using uppercase letters)
      84             :       SHA-1 hash value of the issuer DN prefixed with a "crl-" and
      85             :       suffixed with a ".db".  Thus the length of the filename is 47.
      86             : 
      87             : 
      88             : */
      89             : 
      90             : #include <config.h>
      91             : 
      92             : #include <stdio.h>
      93             : #include <stdlib.h>
      94             : #include <errno.h>
      95             : #include <string.h>
      96             : #include <sys/stat.h>
      97             : #include <assert.h>
      98             : #include <dirent.h>
      99             : #include <fcntl.h>
     100             : #include <unistd.h>
     101             : #ifndef HAVE_W32_SYSTEM
     102             : #include <sys/utsname.h>
     103             : #endif
     104             : #ifdef MKDIR_TAKES_ONE_ARG
     105             : #undef mkdir
     106             : #define mkdir(a,b) mkdir(a)
     107             : #endif
     108             : 
     109             : #include "dirmngr.h"
     110             : #include "validate.h"
     111             : #include "certcache.h"
     112             : #include "crlcache.h"
     113             : #include "crlfetch.h"
     114             : #include "misc.h"
     115             : #include "cdb.h"
     116             : 
     117             : /* Change this whenever the format changes */
     118             : #define DBDIR_D "crls.d"
     119             : #define DBDIRFILE "DIR.txt"
     120             : #define DBDIRVERSION 1
     121             : 
     122             : /* The number of DB files we may have open at one time.  We need to
     123             :    limit this because there is no guarantee that the number of issuers
     124             :    has a upper limit.  We are currently using mmap, so it is a good
     125             :    idea anyway to limit the number of opened cache files. */
     126             : #define MAX_OPEN_DB_FILES 5
     127             : 
     128             : 
     129             : static const char oidstr_crlNumber[] = "2.5.29.20";
     130             : static const char oidstr_issuingDistributionPoint[] = "2.5.29.28";
     131             : static const char oidstr_authorityKeyIdentifier[] = "2.5.29.35";
     132             : 
     133             : 
     134             : /* Definition of one cached item. */
     135             : struct crl_cache_entry_s
     136             : {
     137             :   struct crl_cache_entry_s *next;
     138             :   int deleted;        /* True if marked for deletion. */
     139             :   int mark;           /* Internally used by update_dir. */
     140             :   unsigned int lineno;/* A 0 indicates a new entry. */
     141             :   char *release_ptr;  /* The actual allocated memory. */
     142             :   char *url;          /* Points into RELEASE_PTR. */
     143             :   char *issuer;       /* Ditto. */
     144             :   char *issuer_hash;  /* Ditto. */
     145             :   char *dbfile_hash;  /* MD5 sum of the cache file, points into RELEASE_PTR.*/
     146             :   int invalid;        /* Can't use this CRL. */
     147             :   int user_trust_req; /* User supplied root certificate required.  */
     148             :   char *check_trust_anchor;  /* Malloced fingerprint.  */
     149             :   ksba_isotime_t this_update;
     150             :   ksba_isotime_t next_update;
     151             :   ksba_isotime_t last_refresh; /* Use for the force_crl_refresh feature. */
     152             :   char *crl_number;
     153             :   char *authority_issuer;
     154             :   char *authority_serialno;
     155             : 
     156             :   struct cdb *cdb;             /* The cache file handle or NULL if not open. */
     157             : 
     158             :   unsigned int cdb_use_count;  /* Current use count. */
     159             :   unsigned int cdb_lru_count;  /* Used for LRU purposes. */
     160             :   int dbfile_checked;          /* Set to true if the dbfile_hash value has
     161             :                                   been checked one. */
     162             : };
     163             : 
     164             : 
     165             : /* Definition of the entire cache object. */
     166             : struct crl_cache_s
     167             : {
     168             :   crl_cache_entry_t entries;
     169             : };
     170             : 
     171             : typedef struct crl_cache_s *crl_cache_t;
     172             : 
     173             : 
     174             : /* Prototypes.  */
     175             : static crl_cache_entry_t find_entry (crl_cache_entry_t first,
     176             :                                      const char *issuer_hash);
     177             : 
     178             : 
     179             : 
     180             : /* The currently loaded cache object.  This is usually initialized
     181             :    right at startup.  */
     182             : static crl_cache_t current_cache;
     183             : 
     184             : 
     185             : 
     186             : 
     187             : 
     188             : /* Return the current cache object or bail out if it is has not yet
     189             :    been initialized.  */
     190             : static crl_cache_t
     191           0 : get_current_cache (void)
     192             : {
     193           0 :   if (!current_cache)
     194           0 :     log_fatal ("CRL cache has not yet been initialized\n");
     195           0 :   return current_cache;
     196             : }
     197             : 
     198             : 
     199             : /*
     200             :    Create ae directory if it does not yet exists.  Returns on
     201             :    success, or -1 on error.
     202             :  */
     203             : static int
     204           0 : create_directory_if_needed (const char *name)
     205             : {
     206             :   DIR *dir;
     207             :   char *fname;
     208             : 
     209           0 :   fname = make_filename (opt.homedir_cache, name, NULL);
     210           0 :   dir = opendir (fname);
     211           0 :   if (!dir)
     212             :     {
     213           0 :       log_info (_("creating directory '%s'\n"), fname);
     214           0 :       if (mkdir (fname, S_IRUSR|S_IWUSR|S_IXUSR) )
     215             :         {
     216           0 :           int save_errno = errno;
     217           0 :           log_error (_("error creating directory '%s': %s\n"),
     218           0 :                      fname, strerror (errno));
     219           0 :           xfree (fname);
     220           0 :           gpg_err_set_errno (save_errno);
     221           0 :           return -1;
     222             :         }
     223             :     }
     224             :   else
     225           0 :     closedir (dir);
     226           0 :   xfree (fname);
     227           0 :   return 0;
     228             : }
     229             : 
     230             : /* Remove all files from the cache directory.  If FORCE is not true,
     231             :    some sanity checks on the filenames are done. Return 0 if
     232             :    everything went fine. */
     233             : static int
     234           0 : cleanup_cache_dir (int force)
     235             : {
     236           0 :   char *dname = make_filename (opt.homedir_cache, DBDIR_D, NULL);
     237             :   DIR *dir;
     238             :   struct dirent *de;
     239           0 :   int problem = 0;
     240             : 
     241           0 :   if (!force)
     242             :     { /* Very minor sanity checks. */
     243           0 :       if (!strcmp (dname, "~/") || !strcmp (dname, "/" ))
     244             :         {
     245           0 :           log_error (_("ignoring database dir '%s'\n"), dname);
     246           0 :           xfree (dname);
     247           0 :           return -1;
     248             :         }
     249             :     }
     250             : 
     251           0 :   dir = opendir (dname);
     252           0 :   if (!dir)
     253             :     {
     254           0 :       log_error (_("error reading directory '%s': %s\n"),
     255           0 :                  dname, strerror (errno));
     256           0 :       xfree (dname);
     257           0 :       return -1;
     258             :     }
     259             : 
     260           0 :   while ((de = readdir (dir)))
     261             :     {
     262           0 :       if (strcmp (de->d_name, "." ) && strcmp (de->d_name, ".."))
     263             :         {
     264           0 :           char *cdbname = make_filename (dname, de->d_name, NULL);
     265             :           int okay;
     266             :           struct stat sbuf;
     267             : 
     268           0 :           if (force)
     269           0 :             okay = 1;
     270             :           else
     271           0 :             okay = (!stat (cdbname, &sbuf) && S_ISREG (sbuf.st_mode));
     272             : 
     273           0 :           if (okay)
     274             :             {
     275           0 :               log_info (_("removing cache file '%s'\n"), cdbname);
     276           0 :               if (gnupg_remove (cdbname))
     277             :                 {
     278           0 :                   log_error ("failed to remove '%s': %s\n",
     279           0 :                              cdbname, strerror (errno));
     280           0 :                   problem = -1;
     281             :                 }
     282             :             }
     283             :           else
     284           0 :             log_info (_("not removing file '%s'\n"), cdbname);
     285           0 :           xfree (cdbname);
     286             :         }
     287             :     }
     288           0 :   xfree (dname);
     289           0 :   closedir (dir);
     290           0 :   return problem;
     291             : }
     292             : 
     293             : 
     294             : /* Read the next line from the file FP and return the line in an
     295             :    malloced buffer.  Return NULL on error or EOF.  There is no
     296             :    limitation os the line length.  The trailing linefeed has been
     297             :    removed, the function will read the last line of a file, even if
     298             :    that is not terminated by a LF. */
     299             : static char *
     300           0 : next_line_from_file (estream_t fp, gpg_error_t *r_err)
     301             : {
     302             :   char buf[300];
     303           0 :   char *largebuf = NULL;
     304             :   size_t buflen;
     305           0 :   size_t len = 0;
     306             :   unsigned char *p;
     307             :   int c;
     308             :   char *tmpbuf;
     309             : 
     310           0 :   *r_err = 0;
     311           0 :   p = buf;
     312           0 :   buflen = sizeof buf - 1;
     313           0 :   while ((c=es_getc (fp)) != EOF && c != '\n')
     314             :     {
     315           0 :       if (len >= buflen)
     316             :         {
     317           0 :           if (!largebuf)
     318             :             {
     319           0 :               buflen += 1024;
     320           0 :               largebuf = xtrymalloc ( buflen + 1 );
     321           0 :               if (!largebuf)
     322             :                 {
     323           0 :                   *r_err = gpg_error_from_syserror ();
     324           0 :                   return NULL;
     325             :                 }
     326           0 :               memcpy (largebuf, buf, len);
     327             :             }
     328             :           else
     329             :             {
     330           0 :               buflen += 1024;
     331           0 :               tmpbuf = xtryrealloc (largebuf, buflen + 1);
     332           0 :               if (!tmpbuf)
     333             :                 {
     334           0 :                   *r_err = gpg_error_from_syserror ();
     335           0 :                   xfree (largebuf);
     336           0 :                   return NULL;
     337             :                 }
     338           0 :               largebuf = tmpbuf;
     339             :             }
     340           0 :           p = largebuf;
     341             :         }
     342           0 :       p[len++] = c;
     343             :     }
     344           0 :   if (c == EOF && !len)
     345           0 :     return NULL;
     346           0 :   p[len] = 0;
     347             : 
     348           0 :   if (largebuf)
     349           0 :     tmpbuf = xtryrealloc (largebuf, len+1);
     350             :   else
     351           0 :     tmpbuf = xtrystrdup (buf);
     352           0 :   if (!tmpbuf)
     353             :     {
     354           0 :       *r_err = gpg_error_from_syserror ();
     355           0 :       xfree (largebuf);
     356             :     }
     357           0 :   return tmpbuf;
     358             : }
     359             : 
     360             : 
     361             : /* Release one cache entry.  */
     362             : static void
     363           0 : release_one_cache_entry (crl_cache_entry_t entry)
     364             : {
     365           0 :   if (entry)
     366             :     {
     367           0 :       if (entry->cdb)
     368             :         {
     369           0 :           int fd = cdb_fileno (entry->cdb);
     370           0 :           cdb_free (entry->cdb);
     371           0 :           xfree (entry->cdb);
     372           0 :           if (close (fd))
     373           0 :             log_error (_("error closing cache file: %s\n"), strerror(errno));
     374             :         }
     375           0 :       xfree (entry->release_ptr);
     376           0 :       xfree (entry->check_trust_anchor);
     377           0 :       xfree (entry);
     378             :     }
     379           0 : }
     380             : 
     381             : 
     382             : /* Release the CACHE object. */
     383             : static void
     384           0 : release_cache (crl_cache_t cache)
     385             : {
     386             :   crl_cache_entry_t entry, entry2;
     387             : 
     388           0 :   if (!cache)
     389           0 :     return;
     390             : 
     391           0 :   for (entry = cache->entries; entry; entry = entry2)
     392             :     {
     393           0 :       entry2 = entry->next;
     394           0 :       release_one_cache_entry (entry);
     395             :     }
     396           0 :   cache->entries = NULL;
     397           0 :   xfree (cache);
     398             : }
     399             : 
     400             : 
     401             : /* Open the dir file FNAME or create a new one if it does not yet
     402             :    exist. */
     403             : static estream_t
     404           0 : open_dir_file (const char *fname)
     405             : {
     406             :   estream_t fp;
     407             : 
     408           0 :   fp = es_fopen (fname, "r");
     409           0 :   if (!fp)
     410             :     {
     411           0 :       log_error (_("failed to open cache dir file '%s': %s\n"),
     412           0 :                  fname, strerror (errno));
     413             : 
     414             :       /* Make sure that the directory exists, try to create if otherwise. */
     415           0 :       if (create_directory_if_needed (NULL)
     416           0 :           || create_directory_if_needed (DBDIR_D))
     417           0 :         return NULL;
     418           0 :       fp = es_fopen (fname, "w");
     419           0 :       if (!fp)
     420             :         {
     421           0 :           log_error (_("error creating new cache dir file '%s': %s\n"),
     422           0 :                      fname, strerror (errno));
     423           0 :           return NULL;
     424             :         }
     425           0 :       es_fprintf (fp, "v:%d:\n", DBDIRVERSION);
     426           0 :       if (es_ferror (fp))
     427             :         {
     428           0 :           log_error (_("error writing new cache dir file '%s': %s\n"),
     429           0 :                      fname, strerror (errno));
     430           0 :           es_fclose (fp);
     431           0 :           return NULL;
     432             :         }
     433           0 :       if (es_fclose (fp))
     434             :         {
     435           0 :           log_error (_("error closing new cache dir file '%s': %s\n"),
     436           0 :                      fname, strerror (errno));
     437           0 :           return NULL;
     438             :         }
     439             : 
     440           0 :       log_info (_("new cache dir file '%s' created\n"), fname);
     441             : 
     442           0 :       fp = es_fopen (fname, "r");
     443           0 :       if (!fp)
     444             :         {
     445           0 :           log_error (_("failed to re-open cache dir file '%s': %s\n"),
     446           0 :                      fname, strerror (errno));
     447           0 :           return NULL;
     448             :         }
     449             :     }
     450             : 
     451           0 :   return fp;
     452             : }
     453             : 
     454             : /* Helper for open_dir. */
     455             : static gpg_error_t
     456           0 : check_dir_version (estream_t *fpadr, const char *fname,
     457             :                          unsigned int *lineno,
     458             :                          int cleanup_on_mismatch)
     459             : {
     460             :   char *line;
     461           0 :   gpg_error_t lineerr = 0;
     462           0 :   estream_t fp = *fpadr;
     463           0 :   int created = 0;
     464             : 
     465             :  retry:
     466           0 :   while ((line = next_line_from_file (fp, &lineerr)))
     467             :     {
     468           0 :       ++*lineno;
     469           0 :       if (*line == 'v' && line[1] == ':')
     470             :         break;
     471           0 :       else if (*line != '#')
     472             :         {
     473           0 :           log_error (_("first record of '%s' is not the version\n"), fname);
     474           0 :           xfree (line);
     475           0 :           return gpg_error (GPG_ERR_CONFIGURATION);
     476             :         }
     477           0 :       xfree (line);
     478             :     }
     479           0 :   if (lineerr)
     480           0 :     return lineerr;
     481             : 
     482             :   /* The !line catches the case of an empty DIR file.  We handle this
     483             :      the same as a non-matching version.  */
     484           0 :   if (!line || strtol (line+2, NULL, 10) != DBDIRVERSION)
     485             :     {
     486           0 :       if (!created && cleanup_on_mismatch)
     487             :         {
     488           0 :           log_error (_("old version of cache directory - cleaning up\n"));
     489           0 :           es_fclose (fp);
     490           0 :           *fpadr = NULL;
     491           0 :           if (!cleanup_cache_dir (1))
     492             :             {
     493           0 :               *lineno = 0;
     494           0 :               fp = *fpadr = open_dir_file (fname);
     495           0 :               if (!fp)
     496             :                 {
     497           0 :                   xfree (line);
     498           0 :                   return gpg_error (GPG_ERR_CONFIGURATION);
     499             :                 }
     500           0 :               created = 1;
     501           0 :               goto retry;
     502             :             }
     503             :         }
     504           0 :       log_error (_("old version of cache directory - giving up\n"));
     505           0 :       xfree (line);
     506           0 :       return gpg_error (GPG_ERR_CONFIGURATION);
     507             :     }
     508           0 :   xfree (line);
     509           0 :   return 0;
     510             : }
     511             : 
     512             : 
     513             : /* Open the dir file and read in all available information.  Store
     514             :    that in a newly allocated cache object and return that if
     515             :    everything worked out fine.  Create the cache directory and the dir
     516             :    if it does not yet exist.  Remove all files in that directory if
     517             :    the version does not match. */
     518             : static gpg_error_t
     519           0 : open_dir (crl_cache_t *r_cache)
     520             : {
     521             :   crl_cache_t cache;
     522             :   char *fname;
     523           0 :   char *line = NULL;
     524           0 :   gpg_error_t lineerr = 0;
     525             :   estream_t fp;
     526             :   crl_cache_entry_t entry, *entrytail;
     527             :   unsigned int lineno;
     528           0 :   gpg_error_t err = 0;
     529           0 :   int anyerr = 0;
     530             : 
     531           0 :   cache = xtrycalloc (1, sizeof *cache);
     532           0 :   if (!cache)
     533           0 :     return gpg_error_from_syserror ();
     534             : 
     535           0 :   fname = make_filename (opt.homedir_cache, DBDIR_D, DBDIRFILE, NULL);
     536             : 
     537           0 :   lineno = 0;
     538           0 :   fp = open_dir_file (fname);
     539           0 :   if (!fp)
     540             :     {
     541           0 :       err = gpg_error (GPG_ERR_CONFIGURATION);
     542           0 :       goto leave;
     543             :     }
     544             : 
     545           0 :   err = check_dir_version (&fp, fname, &lineno, 1);
     546           0 :   if (err)
     547           0 :     goto leave;
     548             : 
     549             : 
     550             :   /* Read in all supported entries from the dir file. */
     551           0 :   cache->entries = NULL;
     552           0 :   entrytail = &cache->entries;
     553           0 :   xfree (line);
     554           0 :   while ((line = next_line_from_file (fp, &lineerr)))
     555             :     {
     556             :       int fieldno;
     557             :       char *p, *endp;
     558             : 
     559           0 :       lineno++;
     560           0 :       if ( *line == 'c' || *line == 'u' || *line == 'i' )
     561             :         {
     562           0 :           entry = xtrycalloc (1, sizeof *entry);
     563           0 :           if (!entry)
     564             :             {
     565           0 :               err = gpg_error_from_syserror ();
     566           0 :               goto leave;
     567             :             }
     568           0 :           entry->lineno = lineno;
     569           0 :           entry->release_ptr = line;
     570           0 :           if (*line == 'i')
     571             :             {
     572           0 :               entry->invalid = atoi (line+1);
     573           0 :               if (entry->invalid < 1)
     574           0 :                 entry->invalid = 1;
     575             :             }
     576           0 :           else if (*line == 'u')
     577           0 :             entry->user_trust_req = 1;
     578             : 
     579           0 :           for (fieldno=1, p = line; p; p = endp, fieldno++)
     580             :             {
     581           0 :               endp = strchr (p, ':');
     582           0 :               if (endp)
     583           0 :                 *endp++ = '\0';
     584             : 
     585           0 :               switch (fieldno)
     586             :                 {
     587           0 :                 case 1: /* record type */ break;
     588           0 :                 case 2: entry->issuer_hash = p; break;
     589           0 :                 case 3: entry->issuer = unpercent_string (p); break;
     590           0 :                 case 4: entry->url = unpercent_string (p); break;
     591             :                 case 5:
     592           0 :                   strncpy (entry->this_update, p, 15);
     593           0 :                   entry->this_update[15] = 0;
     594           0 :                   break;
     595             :                 case 6:
     596           0 :                   strncpy (entry->next_update, p, 15);
     597           0 :                   entry->next_update[15] = 0;
     598           0 :                   break;
     599           0 :                 case 7: entry->dbfile_hash = p; break;
     600           0 :                 case 8: if (*p) entry->crl_number = p; break;
     601             :                 case 9:
     602           0 :                   if (*p)
     603           0 :                     entry->authority_issuer = unpercent_string (p);
     604           0 :                   break;
     605             :                 case 10:
     606           0 :                   if (*p)
     607           0 :                     entry->authority_serialno = unpercent_string (p);
     608           0 :                   break;
     609             :                 case 11:
     610           0 :                   if (*p)
     611           0 :                     entry->check_trust_anchor = xtrystrdup (p);
     612           0 :                   break;
     613             :                 default:
     614           0 :                   if (*p)
     615           0 :                     log_info (_("extra field detected in crl record of "
     616             :                                 "'%s' line %u\n"), fname, lineno);
     617           0 :                   break;
     618             :                 }
     619             :             }
     620             : 
     621           0 :           if (!entry->issuer_hash)
     622             :             {
     623           0 :               log_info (_("invalid line detected in '%s' line %u\n"),
     624             :                         fname, lineno);
     625           0 :               xfree (entry);
     626           0 :               entry = NULL;
     627             :             }
     628           0 :           else if (find_entry (cache->entries, entry->issuer_hash))
     629             :             {
     630             :               /* Fixme: The duplicate checking used is not very
     631             :                  effective for large numbers of issuers. */
     632           0 :               log_info (_("duplicate entry detected in '%s' line %u\n"),
     633             :                         fname, lineno);
     634           0 :               xfree (entry);
     635           0 :               entry = NULL;
     636             :             }
     637             :           else
     638             :             {
     639           0 :               line = NULL;
     640           0 :               *entrytail = entry;
     641           0 :               entrytail = &entry->next;
     642             :             }
     643             :         }
     644           0 :       else if (*line == '#')
     645             :         ;
     646             :       else
     647           0 :         log_info (_("unsupported record type in '%s' line %u skipped\n"),
     648             :                   fname, lineno);
     649             : 
     650           0 :       if (line)
     651           0 :         xfree (line);
     652             :     }
     653           0 :   if (lineerr)
     654             :     {
     655           0 :       err = lineerr;
     656           0 :       log_error (_("error reading '%s': %s\n"), fname, gpg_strerror (err));
     657           0 :       goto leave;
     658             :     }
     659           0 :   if (es_ferror (fp))
     660             :     {
     661           0 :       log_error (_("error reading '%s': %s\n"), fname, strerror (errno));
     662           0 :       err = gpg_error (GPG_ERR_CONFIGURATION);
     663           0 :       goto leave;
     664             :     }
     665             : 
     666             :   /* Now do some basic checks on the data. */
     667           0 :   for (entry = cache->entries; entry; entry = entry->next)
     668             :     {
     669           0 :       assert (entry->lineno);
     670           0 :       if (strlen (entry->issuer_hash) != 40)
     671             :         {
     672           0 :           anyerr++;
     673           0 :           log_error (_("invalid issuer hash in '%s' line %u\n"),
     674             :                      fname, entry->lineno);
     675             :         }
     676           0 :       else if ( !*entry->issuer )
     677             :         {
     678           0 :           anyerr++;
     679           0 :           log_error (_("no issuer DN in '%s' line %u\n"),
     680             :                      fname, entry->lineno);
     681             :         }
     682           0 :       else if ( check_isotime (entry->this_update)
     683           0 :                 || check_isotime (entry->next_update))
     684             :         {
     685           0 :           anyerr++;
     686           0 :           log_error (_("invalid timestamp in '%s' line %u\n"),
     687             :                      fname, entry->lineno);
     688             :         }
     689             : 
     690             :       /* Checks not leading to an immediate fail. */
     691           0 :       if (strlen (entry->dbfile_hash) != 32)
     692           0 :         log_info (_("WARNING: invalid cache file hash in '%s' line %u\n"),
     693             :                   fname, entry->lineno);
     694             :     }
     695             : 
     696           0 :   if (anyerr)
     697             :     {
     698           0 :       log_error (_("detected errors in cache dir file\n"));
     699           0 :       log_info (_("please check the reason and manually delete that file\n"));
     700           0 :       err = gpg_error (GPG_ERR_CONFIGURATION);
     701             :     }
     702             : 
     703             : 
     704             :  leave:
     705           0 :   es_fclose (fp);
     706           0 :   xfree (line);
     707           0 :   xfree (fname);
     708           0 :   if (err)
     709             :     {
     710           0 :       release_cache (cache);
     711           0 :       cache = NULL;
     712             :     }
     713           0 :   *r_cache = cache;
     714           0 :   return err;
     715             : }
     716             : 
     717             : static void
     718           0 : write_percented_string (const char *s, estream_t fp)
     719             : {
     720           0 :   for (; *s; s++)
     721           0 :     if (*s == ':')
     722           0 :       es_fputs ("%3A", fp);
     723           0 :     else if (*s == '\n')
     724           0 :       es_fputs ("%0A", fp);
     725           0 :     else if (*s == '\r')
     726           0 :       es_fputs ("%0D", fp);
     727             :     else
     728           0 :       es_putc (*s, fp);
     729           0 : }
     730             : 
     731             : 
     732             : static void
     733           0 : write_dir_line_crl (estream_t fp, crl_cache_entry_t e)
     734             : {
     735           0 :   if (e->invalid)
     736           0 :     es_fprintf (fp, "i%d", e->invalid);
     737           0 :   else if (e->user_trust_req)
     738           0 :     es_putc ('u', fp);
     739             :   else
     740           0 :     es_putc ('c', fp);
     741           0 :   es_putc (':', fp);
     742           0 :   es_fputs (e->issuer_hash, fp);
     743           0 :   es_putc (':', fp);
     744           0 :   write_percented_string (e->issuer, fp);
     745           0 :   es_putc (':', fp);
     746           0 :   write_percented_string (e->url, fp);
     747           0 :   es_putc (':', fp);
     748           0 :   es_fwrite (e->this_update, 15, 1, fp);
     749           0 :   es_putc (':', fp);
     750           0 :   es_fwrite (e->next_update, 15, 1, fp);
     751           0 :   es_putc (':', fp);
     752           0 :   es_fputs (e->dbfile_hash, fp);
     753           0 :   es_putc (':', fp);
     754           0 :   if (e->crl_number)
     755           0 :     es_fputs (e->crl_number, fp);
     756           0 :   es_putc (':', fp);
     757           0 :   if (e->authority_issuer)
     758           0 :     write_percented_string (e->authority_issuer, fp);
     759           0 :   es_putc (':', fp);
     760           0 :   if (e->authority_serialno)
     761           0 :     es_fputs (e->authority_serialno, fp);
     762           0 :   es_putc (':', fp);
     763           0 :   if (e->check_trust_anchor && e->user_trust_req)
     764           0 :     es_fputs (e->check_trust_anchor, fp);
     765           0 :   es_putc ('\n', fp);
     766           0 : }
     767             : 
     768             : 
     769             : /* Update the current dir file using the cache. */
     770             : static gpg_error_t
     771           0 : update_dir (crl_cache_t cache)
     772             : {
     773           0 :   char *fname = NULL;
     774           0 :   char *tmpfname = NULL;
     775           0 :   char *line = NULL;
     776           0 :   gpg_error_t lineerr = 0;
     777             :   estream_t fp;
     778           0 :   estream_t fpout = NULL;
     779             :   crl_cache_entry_t e;
     780             :   unsigned int lineno;
     781           0 :   gpg_error_t err = 0;
     782             : 
     783           0 :   fname = make_filename (opt.homedir_cache, DBDIR_D, DBDIRFILE, NULL);
     784             : 
     785             :   /* Fixme: Take an update file lock here. */
     786             : 
     787           0 :   for (e= cache->entries; e; e = e->next)
     788           0 :     e->mark = 1;
     789             : 
     790           0 :   lineno = 0;
     791           0 :   fp = es_fopen (fname, "r");
     792           0 :   if (!fp)
     793             :     {
     794           0 :       err = gpg_error_from_errno (errno);
     795           0 :       log_error (_("failed to open cache dir file '%s': %s\n"),
     796           0 :                  fname, strerror (errno));
     797           0 :       goto leave;
     798             :     }
     799           0 :   err = check_dir_version (&fp, fname, &lineno, 0);
     800           0 :   if (err)
     801           0 :     goto leave;
     802           0 :   es_rewind (fp);
     803           0 :   lineno = 0;
     804             : 
     805             :   /* Create a temporary DIR file. */
     806             :   {
     807             :     char *tmpbuf, *p;
     808             :     const char *nodename;
     809             : #ifndef HAVE_W32_SYSTEM
     810             :     struct utsname utsbuf;
     811             : #endif
     812             : 
     813             : #ifdef HAVE_W32_SYSTEM
     814             :     nodename = "unknown";
     815             : #else
     816           0 :     if (uname (&utsbuf))
     817           0 :       nodename = "unknown";
     818             :     else
     819           0 :       nodename = utsbuf.nodename;
     820             : #endif
     821             : 
     822           0 :     gpgrt_asprintf (&tmpbuf, "DIR-tmp-%s-%u-%p.txt.tmp",
     823           0 :                     nodename, (unsigned int)getpid (), &tmpbuf);
     824           0 :     if (!tmpbuf)
     825             :       {
     826           0 :         err = gpg_error_from_errno (errno);
     827           0 :         log_error (_("failed to create temporary cache dir file '%s': %s\n"),
     828           0 :                    tmpfname, strerror (errno));
     829           0 :         goto leave;
     830             :       }
     831           0 :     for (p=tmpbuf; *p; p++)
     832           0 :       if (*p == '/')
     833           0 :         *p = '.';
     834           0 :     tmpfname = make_filename (opt.homedir_cache, DBDIR_D, tmpbuf, NULL);
     835           0 :     xfree (tmpbuf);
     836             :   }
     837           0 :   fpout = es_fopen (tmpfname, "w");
     838           0 :   if (!fpout)
     839             :     {
     840           0 :       err = gpg_error_from_errno (errno);
     841           0 :       log_error (_("failed to create temporary cache dir file '%s': %s\n"),
     842           0 :                  tmpfname, strerror (errno));
     843           0 :       goto leave;
     844             :     }
     845             : 
     846           0 :   while ((line = next_line_from_file (fp, &lineerr)))
     847             :     {
     848           0 :       lineno++;
     849           0 :       if (*line == 'c' || *line == 'u' || *line == 'i')
     850           0 :         {
     851             :           /* Extract the issuer hash field. */
     852             :           char *fieldp, *endp;
     853             : 
     854           0 :           fieldp = strchr (line, ':');
     855           0 :           endp = fieldp? strchr (++fieldp, ':') : NULL;
     856           0 :           if (endp)
     857             :             {
     858             :               /* There should be no percent within the issuer hash
     859             :                  field, thus we can compare it pretty easily. */
     860           0 :               *endp = 0;
     861           0 :               e = find_entry ( cache->entries, fieldp);
     862           0 :               *endp = ':'; /* Restore original line. */
     863           0 :               if (e && e->deleted)
     864             :                 {
     865             :                   /* Marked for deletion, so don't write it. */
     866           0 :                   e->mark = 0;
     867             :                 }
     868           0 :               else if (e)
     869             :                 {
     870             :                   /* Yep, this is valid entry we know about; write it out */
     871           0 :                   write_dir_line_crl (fpout, e);
     872           0 :                   e->mark = 0;
     873             :                 }
     874             :               else
     875             :                 { /* We ignore entries we don't have in our cache
     876             :                      because they may have been added in the meantime
     877             :                      by other instances of dirmngr. */
     878           0 :                   es_fprintf (fpout, "# Next line added by "
     879             :                               "another process; our pid is %lu\n",
     880           0 :                               (unsigned long)getpid ());
     881           0 :                   es_fputs (line, fpout);
     882           0 :                   es_putc ('\n', fpout);
     883             :                 }
     884             :             }
     885             :           else
     886             :             {
     887           0 :               es_fputs ("# Invalid line detected: ", fpout);
     888           0 :               es_fputs (line, fpout);
     889           0 :               es_putc ('\n', fpout);
     890             :             }
     891             :         }
     892             :       else
     893             :         {
     894             :           /* Write out all non CRL lines as they are. */
     895           0 :           es_fputs (line, fpout);
     896           0 :           es_putc ('\n', fpout);
     897             :         }
     898             : 
     899           0 :       xfree (line);
     900             :     }
     901           0 :   if (!es_ferror (fp) && !es_ferror (fpout) && !lineerr)
     902             :     {
     903             :       /* Write out the remaining entries. */
     904           0 :       for (e= cache->entries; e; e = e->next)
     905           0 :         if (e->mark)
     906             :           {
     907           0 :             if (!e->deleted)
     908           0 :               write_dir_line_crl (fpout, e);
     909           0 :             e->mark = 0;
     910             :           }
     911             :     }
     912           0 :   if (lineerr)
     913             :     {
     914           0 :       err = lineerr;
     915           0 :       log_error (_("error reading '%s': %s\n"), fname, gpg_strerror (err));
     916           0 :       goto leave;
     917             :     }
     918           0 :   if (es_ferror (fp))
     919             :     {
     920           0 :       err = gpg_error_from_errno (errno);
     921           0 :       log_error (_("error reading '%s': %s\n"), fname, strerror (errno));
     922             :     }
     923           0 :   if (es_ferror (fpout))
     924             :     {
     925           0 :       err = gpg_error_from_errno (errno);
     926           0 :       log_error (_("error writing '%s': %s\n"), tmpfname, strerror (errno));
     927             :     }
     928           0 :   if (err)
     929           0 :     goto leave;
     930             : 
     931             :   /* Rename the files. */
     932           0 :   es_fclose (fp);
     933           0 :   fp = NULL;
     934           0 :   if (es_fclose (fpout))
     935             :     {
     936           0 :       err = gpg_error_from_errno (errno);
     937           0 :       log_error (_("error closing '%s': %s\n"), tmpfname, strerror (errno));
     938           0 :       goto leave;
     939             :     }
     940           0 :   fpout = NULL;
     941             : 
     942             : #ifdef HAVE_W32_SYSTEM
     943             :   /* No atomic mv on W32 systems.  */
     944             :   gnupg_remove (fname);
     945             : #endif
     946           0 :   if (rename (tmpfname, fname))
     947             :     {
     948           0 :       err = gpg_error_from_errno (errno);
     949           0 :       log_error (_("error renaming '%s' to '%s': %s\n"),
     950           0 :                  tmpfname, fname, strerror (errno));
     951           0 :       goto leave;
     952             :     }
     953             : 
     954             :  leave:
     955             :   /* Fixme: Relinquish update lock. */
     956           0 :   xfree (line);
     957           0 :   es_fclose (fp);
     958           0 :   xfree (fname);
     959           0 :   if (fpout)
     960             :     {
     961           0 :       es_fclose (fpout);
     962           0 :       if (err && tmpfname)
     963           0 :         gnupg_remove (tmpfname);
     964             :     }
     965           0 :   xfree (tmpfname);
     966           0 :   return err;
     967             : }
     968             : 
     969             : 
     970             : 
     971             : 
     972             : /* Create the filename for the cache file from the 40 byte ISSUER_HASH
     973             :    string. Caller must release the return string. */
     974             : static char *
     975           0 : make_db_file_name (const char *issuer_hash)
     976             : {
     977             :   char bname[50];
     978             : 
     979           0 :   assert (strlen (issuer_hash) == 40);
     980           0 :   memcpy (bname, "crl-", 4);
     981           0 :   memcpy (bname + 4, issuer_hash, 40);
     982           0 :   strcpy (bname + 44, ".db");
     983           0 :   return make_filename (opt.homedir_cache, DBDIR_D, bname, NULL);
     984             : }
     985             : 
     986             : 
     987             : /* Hash the file FNAME and return the MD5 digest in MD5BUFFER. The
     988             :    caller must allocate MD%buffer wityh at least 16 bytes. Returns 0
     989             :    on success. */
     990             : static int
     991           0 : hash_dbfile (const char *fname, unsigned char *md5buffer)
     992             : {
     993             :   estream_t fp;
     994             :   char *buffer;
     995             :   size_t n;
     996             :   gcry_md_hd_t md5;
     997             :   gpg_error_t err;
     998             : 
     999           0 :   buffer = xtrymalloc (65536);
    1000           0 :   fp = buffer? es_fopen (fname, "rb") : NULL;
    1001           0 :   if (!fp)
    1002             :     {
    1003           0 :       log_error (_("can't hash '%s': %s\n"), fname, strerror (errno));
    1004           0 :       xfree (buffer);
    1005           0 :       return -1;
    1006             :     }
    1007             : 
    1008           0 :   err = gcry_md_open (&md5, GCRY_MD_MD5, 0);
    1009           0 :   if (err)
    1010             :     {
    1011           0 :       log_error (_("error setting up MD5 hash context: %s\n"),
    1012             :                  gpg_strerror (err));
    1013           0 :       xfree (buffer);
    1014           0 :       es_fclose (fp);
    1015           0 :       return -1;
    1016             :     }
    1017             : 
    1018             :   /* We better hash some information about the cache file layout in. */
    1019           0 :   sprintf (buffer, "%.100s/%.100s:%d", DBDIR_D, DBDIRFILE, DBDIRVERSION);
    1020           0 :   gcry_md_write (md5, buffer, strlen (buffer));
    1021             : 
    1022             :   for (;;)
    1023             :     {
    1024           0 :       n = es_fread (buffer, 1, 65536, fp);
    1025           0 :       if (n < 65536 && es_ferror (fp))
    1026             :         {
    1027           0 :           log_error (_("error hashing '%s': %s\n"), fname, strerror (errno));
    1028           0 :           xfree (buffer);
    1029           0 :           es_fclose (fp);
    1030           0 :           gcry_md_close (md5);
    1031           0 :           return -1;
    1032             :         }
    1033           0 :       if (!n)
    1034           0 :         break;
    1035           0 :       gcry_md_write (md5, buffer, n);
    1036           0 :     }
    1037           0 :   es_fclose (fp);
    1038           0 :   xfree (buffer);
    1039           0 :   gcry_md_final (md5);
    1040             : 
    1041           0 :   memcpy (md5buffer, gcry_md_read (md5, GCRY_MD_MD5), 16);
    1042           0 :   gcry_md_close (md5);
    1043           0 :   return 0;
    1044             : }
    1045             : 
    1046             : /* Compare the file FNAME against the dexified MD5 hash MD5HASH and
    1047             :    return 0 if they match. */
    1048             : static int
    1049           0 : check_dbfile (const char *fname, const char *md5hexvalue)
    1050             : {
    1051             :   unsigned char buffer1[16], buffer2[16];
    1052             : 
    1053           0 :   if (strlen (md5hexvalue) != 32)
    1054             :     {
    1055           0 :       log_error (_("invalid formatted checksum for '%s'\n"), fname);
    1056           0 :       return -1;
    1057             :     }
    1058           0 :   unhexify (buffer1, md5hexvalue);
    1059             : 
    1060           0 :   if (hash_dbfile (fname, buffer2))
    1061           0 :     return -1;
    1062             : 
    1063           0 :   return memcmp (buffer1, buffer2, 16);
    1064             : }
    1065             : 
    1066             : 
    1067             : /* Open the cache file for ENTRY.  This function implements a caching
    1068             :    strategy and might close unused cache files. It is required to use
    1069             :    unlock_db_file after using the file. */
    1070             : static struct cdb *
    1071           0 : lock_db_file (crl_cache_t cache, crl_cache_entry_t entry)
    1072             : {
    1073             :   char *fname;
    1074             :   int fd;
    1075             :   int open_count;
    1076             :   crl_cache_entry_t e;
    1077             : 
    1078           0 :   if (entry->cdb)
    1079             :     {
    1080           0 :       entry->cdb_use_count++;
    1081           0 :       return entry->cdb;
    1082             :     }
    1083             : 
    1084           0 :   for (open_count = 0, e = cache->entries; e; e = e->next)
    1085             :     {
    1086           0 :       if (e->cdb)
    1087           0 :         open_count++;
    1088             : /*       log_debug ("CACHE: cdb=%p use_count=%u lru_count=%u\n", */
    1089             : /*                  e->cdb,e->cdb_use_count,e->cdb_lru_count); */
    1090             :     }
    1091             : 
    1092             :   /* If there are too many file open, find the least recent used DB
    1093             :      file and close it.  Note that for Pth thread safeness we need to
    1094             :      use a loop here. */
    1095           0 :   while (open_count >= MAX_OPEN_DB_FILES )
    1096             :     {
    1097           0 :       crl_cache_entry_t last_e = NULL;
    1098           0 :       unsigned int last_lru = (unsigned int)(-1);
    1099             : 
    1100           0 :       for (e = cache->entries; e; e = e->next)
    1101           0 :         if (e->cdb && !e->cdb_use_count && e->cdb_lru_count < last_lru)
    1102             :           {
    1103           0 :             last_lru = e->cdb_lru_count;
    1104           0 :             last_e = e;
    1105             :           }
    1106           0 :       if (!last_e)
    1107             :         {
    1108           0 :           log_error (_("too many open cache files; can't open anymore\n"));
    1109           0 :           return NULL;
    1110             :         }
    1111             : 
    1112             : /*       log_debug ("CACHE: closing file at cdb=%p\n", last_e->cdb); */
    1113             : 
    1114           0 :       fd = cdb_fileno (last_e->cdb);
    1115           0 :       cdb_free (last_e->cdb);
    1116           0 :       xfree (last_e->cdb);
    1117           0 :       last_e->cdb = NULL;
    1118           0 :       if (close (fd))
    1119           0 :         log_error (_("error closing cache file: %s\n"), strerror(errno));
    1120           0 :       open_count--;
    1121             :     }
    1122             : 
    1123             : 
    1124           0 :   fname = make_db_file_name (entry->issuer_hash);
    1125           0 :   if (opt.verbose)
    1126           0 :     log_info (_("opening cache file '%s'\n"), fname );
    1127             : 
    1128           0 :   if (!entry->dbfile_checked)
    1129             :     {
    1130           0 :       if (!check_dbfile (fname, entry->dbfile_hash))
    1131           0 :         entry->dbfile_checked = 1;
    1132             :       /* Note, in case of an error we don't print an error here but
    1133             :          let require the caller to do that check. */
    1134             :     }
    1135             : 
    1136           0 :   entry->cdb = xtrycalloc (1, sizeof *entry->cdb);
    1137           0 :   if (!entry->cdb)
    1138             :     {
    1139           0 :       xfree (fname);
    1140           0 :       return NULL;
    1141             :     }
    1142           0 :   fd = open (fname, O_RDONLY);
    1143           0 :   if (fd == -1)
    1144             :     {
    1145           0 :       log_error (_("error opening cache file '%s': %s\n"),
    1146           0 :                  fname, strerror (errno));
    1147           0 :       xfree (entry->cdb);
    1148           0 :       entry->cdb = NULL;
    1149           0 :       xfree (fname);
    1150           0 :       return NULL;
    1151             :     }
    1152           0 :   if (cdb_init (entry->cdb, fd))
    1153             :     {
    1154           0 :       log_error (_("error initializing cache file '%s' for reading: %s\n"),
    1155           0 :                  fname, strerror (errno));
    1156           0 :       xfree (entry->cdb);
    1157           0 :       entry->cdb = NULL;
    1158           0 :       close (fd);
    1159           0 :       xfree (fname);
    1160           0 :       return NULL;
    1161             :     }
    1162           0 :   xfree (fname);
    1163             : 
    1164           0 :   entry->cdb_use_count = 1;
    1165           0 :   entry->cdb_lru_count = 0;
    1166             : 
    1167           0 :   return entry->cdb;
    1168             : }
    1169             : 
    1170             : /* Unlock a cache file, so that it can be reused. */
    1171             : static void
    1172           0 : unlock_db_file (crl_cache_t cache, crl_cache_entry_t entry)
    1173             : {
    1174           0 :   if (!entry->cdb)
    1175           0 :     log_error (_("calling unlock_db_file on a closed file\n"));
    1176           0 :   else if (!entry->cdb_use_count)
    1177           0 :     log_error (_("calling unlock_db_file on an unlocked file\n"));
    1178             :   else
    1179             :     {
    1180           0 :       entry->cdb_use_count--;
    1181           0 :       entry->cdb_lru_count++;
    1182             :     }
    1183             : 
    1184             :   /* If the entry was marked for deletion in the meantime do it now.
    1185             :      We do this for the sake of Pth thread safeness. */
    1186           0 :   if (!entry->cdb_use_count && entry->deleted)
    1187             :     {
    1188             :       crl_cache_entry_t eprev, enext;
    1189             : 
    1190           0 :       enext = entry->next;
    1191           0 :       for (eprev = cache->entries;
    1192           0 :            eprev && eprev->next != entry; eprev = eprev->next)
    1193             :         ;
    1194           0 :       assert (eprev);
    1195           0 :       if (eprev == cache->entries)
    1196           0 :         cache->entries = enext;
    1197             :       else
    1198           0 :         eprev->next = enext;
    1199             :       /* FIXME: Do we leak ENTRY? */
    1200             :     }
    1201           0 : }
    1202             : 
    1203             : 
    1204             : /* Find ISSUER_HASH in our cache FIRST. This may be used to enumerate
    1205             :    the linked list we use to keep the CRLs of an issuer. */
    1206             : static crl_cache_entry_t
    1207           0 : find_entry (crl_cache_entry_t first, const char *issuer_hash)
    1208             : {
    1209           0 :   while (first && (first->deleted || strcmp (issuer_hash, first->issuer_hash)))
    1210           0 :     first = first->next;
    1211           0 :   return first;
    1212             : }
    1213             : 
    1214             : 
    1215             : /* Create a new CRL cache. This function is usually called only once.
    1216             :    never fail. */
    1217             : void
    1218           0 : crl_cache_init(void)
    1219             : {
    1220           0 :   crl_cache_t cache = NULL;
    1221             :   gpg_error_t err;
    1222             : 
    1223           0 :   if (current_cache)
    1224             :     {
    1225           0 :       log_error ("crl cache has already been initialized - not doing twice\n");
    1226           0 :       return;
    1227             :     }
    1228             : 
    1229           0 :   err = open_dir (&cache);
    1230           0 :   if (err)
    1231           0 :     log_fatal (_("failed to create a new cache object: %s\n"),
    1232             :                gpg_strerror (err));
    1233           0 :   current_cache = cache;
    1234             : }
    1235             : 
    1236             : 
    1237             : /* Remove the cache information and all its resources.  Note that we
    1238             :    still keep the cache on disk. */
    1239             : void
    1240           0 : crl_cache_deinit (void)
    1241             : {
    1242           0 :   if (current_cache)
    1243             :     {
    1244           0 :       release_cache (current_cache);
    1245           0 :       current_cache = NULL;
    1246             :     }
    1247           0 : }
    1248             : 
    1249             : 
    1250             : /* Delete the cache from disk. Return 0 on success.*/
    1251             : int
    1252           0 : crl_cache_flush (void)
    1253             : {
    1254             :   int rc;
    1255             : 
    1256           0 :   rc = cleanup_cache_dir (0)? -1 : 0;
    1257             : 
    1258           0 :   return rc;
    1259             : }
    1260             : 
    1261             : 
    1262             : /* Check whether the certificate identified by ISSUER_HASH and
    1263             :    SN/SNLEN is valid; i.e. not listed in our cache.  With
    1264             :    FORCE_REFRESH set to true, a new CRL will be retrieved even if the
    1265             :    cache has not yet expired.  We use a 30 minutes threshold here so
    1266             :    that invoking this function several times won't load the CRL over
    1267             :    and over.  */
    1268             : static crl_cache_result_t
    1269           0 : cache_isvalid (ctrl_t ctrl, const char *issuer_hash,
    1270             :                const unsigned char *sn, size_t snlen,
    1271             :                int force_refresh)
    1272             : {
    1273           0 :   crl_cache_t cache = get_current_cache ();
    1274             :   crl_cache_result_t retval;
    1275             :   struct cdb *cdb;
    1276             :   int rc;
    1277             :   crl_cache_entry_t entry;
    1278             :   gnupg_isotime_t current_time;
    1279             :   size_t n;
    1280             : 
    1281             :   (void)ctrl;
    1282             : 
    1283           0 :   entry = find_entry (cache->entries, issuer_hash);
    1284           0 :   if (!entry)
    1285             :     {
    1286           0 :       log_info (_("no CRL available for issuer id %s\n"), issuer_hash );
    1287           0 :       return CRL_CACHE_DONTKNOW;
    1288             :     }
    1289             : 
    1290           0 :   gnupg_get_isotime (current_time);
    1291           0 :   if (strcmp (entry->next_update, current_time) < 0 )
    1292             :     {
    1293           0 :       log_info (_("cached CRL for issuer id %s too old; update required\n"),
    1294             :                 issuer_hash);
    1295           0 :       return CRL_CACHE_DONTKNOW;
    1296             :     }
    1297           0 :   if (force_refresh)
    1298             :     {
    1299             :       gnupg_isotime_t tmptime;
    1300             : 
    1301           0 :       if (*entry->last_refresh)
    1302             :         {
    1303           0 :           gnupg_copy_time (tmptime, entry->last_refresh);
    1304           0 :           add_seconds_to_isotime (tmptime, 30 * 60);
    1305           0 :           if (strcmp (tmptime, current_time) < 0 )
    1306             :             {
    1307           0 :               log_info (_("force-crl-refresh active and %d minutes passed for"
    1308             :                           " issuer id %s; update required\n"),
    1309             :                         30, issuer_hash);
    1310           0 :               return CRL_CACHE_DONTKNOW;
    1311             :             }
    1312             :         }
    1313             :       else
    1314             :         {
    1315           0 :           log_info (_("force-crl-refresh active for"
    1316             :                       " issuer id %s; update required\n"),
    1317             :                     issuer_hash);
    1318           0 :           return CRL_CACHE_DONTKNOW;
    1319             :         }
    1320             :     }
    1321             : 
    1322           0 :   if (entry->invalid)
    1323             :     {
    1324           0 :       log_info (_("available CRL for issuer ID %s can't be used\n"),
    1325             :                 issuer_hash);
    1326           0 :       return CRL_CACHE_CANTUSE;
    1327             :     }
    1328             : 
    1329           0 :   cdb = lock_db_file (cache, entry);
    1330           0 :   if (!cdb)
    1331           0 :     return CRL_CACHE_DONTKNOW; /* Hmmm, not the best error code. */
    1332             : 
    1333           0 :   if (!entry->dbfile_checked)
    1334             :     {
    1335           0 :       log_error (_("cached CRL for issuer id %s tampered; we need to update\n")
    1336             :                  , issuer_hash);
    1337           0 :       unlock_db_file (cache, entry);
    1338           0 :       return CRL_CACHE_DONTKNOW;
    1339             :     }
    1340             : 
    1341           0 :   rc = cdb_find (cdb, sn, snlen);
    1342           0 :   if (rc == 1)
    1343             :     {
    1344           0 :       n = cdb_datalen (cdb);
    1345           0 :       if (n != 16)
    1346             :         {
    1347           0 :           log_error (_("WARNING: invalid cache record length for S/N "));
    1348           0 :           log_printf ("0x");
    1349           0 :           log_printhex ("", sn, snlen);
    1350             :         }
    1351           0 :       else if (opt.verbose)
    1352             :         {
    1353             :           unsigned char record[16];
    1354           0 :           char *tmp = hexify_data (sn, snlen, 1);
    1355             : 
    1356           0 :           if (cdb_read (cdb, record, n, cdb_datapos (cdb)))
    1357           0 :             log_error (_("problem reading cache record for S/N %s: %s\n"),
    1358           0 :                        tmp, strerror (errno));
    1359             :           else
    1360           0 :             log_info (_("S/N %s is not valid; reason=%02X  date=%.15s\n"),
    1361           0 :                       tmp, *record, record+1);
    1362           0 :           xfree (tmp);
    1363             :         }
    1364           0 :       retval = CRL_CACHE_INVALID;
    1365             :     }
    1366           0 :   else if (!rc)
    1367             :     {
    1368           0 :       if (opt.verbose)
    1369             :         {
    1370           0 :           char *serialno = hexify_data (sn, snlen, 1);
    1371           0 :           log_info (_("S/N %s is valid, it is not listed in the CRL\n"),
    1372             :                     serialno );
    1373           0 :           xfree (serialno);
    1374             :         }
    1375           0 :       retval = CRL_CACHE_VALID;
    1376             :     }
    1377             :   else
    1378             :     {
    1379           0 :       log_error (_("error getting data from cache file: %s\n"),
    1380           0 :                  strerror (errno));
    1381           0 :       retval = CRL_CACHE_DONTKNOW;
    1382             :     }
    1383             : 
    1384             : 
    1385           0 :   if (entry->user_trust_req
    1386           0 :       && (retval == CRL_CACHE_VALID || retval == CRL_CACHE_INVALID))
    1387             :     {
    1388           0 :       if (!entry->check_trust_anchor)
    1389             :         {
    1390           0 :           log_error ("inconsistent data on user trust check\n");
    1391           0 :           retval = CRL_CACHE_CANTUSE;
    1392             :         }
    1393           0 :       else if (get_istrusted_from_client (ctrl, entry->check_trust_anchor))
    1394             :         {
    1395           0 :           if (opt.verbose)
    1396           0 :             log_info ("no system trust and client does not trust either\n");
    1397           0 :           retval = CRL_CACHE_CANTUSE;
    1398             :         }
    1399             :       else
    1400             :         {
    1401             :           /* Okay, the CRL is considered valid by the client and thus
    1402             :              we can return the result as is.  */
    1403             :         }
    1404             :     }
    1405             : 
    1406           0 :   unlock_db_file (cache, entry);
    1407             : 
    1408           0 :   return retval;
    1409             : }
    1410             : 
    1411             : 
    1412             : /* Check whether the certificate identified by ISSUER_HASH and
    1413             :    SERIALNO is valid; i.e. not listed in our cache.  With
    1414             :    FORCE_REFRESH set to true, a new CRL will be retrieved even if the
    1415             :    cache has not yet expired.  We use a 30 minutes threshold here so
    1416             :    that invoking this function several times won't load the CRL over
    1417             :    and over.  */
    1418             : crl_cache_result_t
    1419           0 : crl_cache_isvalid (ctrl_t ctrl, const char *issuer_hash, const char *serialno,
    1420             :                    int force_refresh)
    1421             : {
    1422             :   crl_cache_result_t result;
    1423             :   unsigned char snbuf_buffer[50];
    1424             :   unsigned char *snbuf;
    1425             :   size_t n;
    1426             : 
    1427           0 :   n = strlen (serialno)/2+1;
    1428           0 :   if (n < sizeof snbuf_buffer - 1)
    1429           0 :     snbuf = snbuf_buffer;
    1430             :   else
    1431             :     {
    1432           0 :       snbuf = xtrymalloc (n);
    1433           0 :       if (!snbuf)
    1434           0 :         return CRL_CACHE_DONTKNOW;
    1435             :     }
    1436             : 
    1437           0 :   n = unhexify (snbuf, serialno);
    1438             : 
    1439           0 :   result = cache_isvalid (ctrl, issuer_hash, snbuf, n, force_refresh);
    1440             : 
    1441           0 :   if (snbuf != snbuf_buffer)
    1442           0 :     xfree (snbuf);
    1443             : 
    1444           0 :   return result;
    1445             : }
    1446             : 
    1447             : 
    1448             : /* Check whether the certificate CERT is valid; i.e. not listed in our
    1449             :    cache.  With FORCE_REFRESH set to true, a new CRL will be retrieved
    1450             :    even if the cache has not yet expired.  We use a 30 minutes
    1451             :    threshold here so that invoking this function several times won't
    1452             :    load the CRL over and over.  */
    1453             : gpg_error_t
    1454           0 : crl_cache_cert_isvalid (ctrl_t ctrl, ksba_cert_t cert,
    1455             :                         int force_refresh)
    1456             : {
    1457             :   gpg_error_t err;
    1458             :   crl_cache_result_t result;
    1459             :   unsigned char issuerhash[20];
    1460             :   char issuerhash_hex[41];
    1461             :   ksba_sexp_t serial;
    1462             :   unsigned char *sn;
    1463             :   size_t snlen;
    1464             :   char *endp, *tmp;
    1465             :   int i;
    1466             : 
    1467             :   /* Compute the hash value of the issuer name.  */
    1468           0 :   tmp = ksba_cert_get_issuer (cert, 0);
    1469           0 :   if (!tmp)
    1470             :     {
    1471           0 :       log_error ("oops: issuer missing in certificate\n");
    1472           0 :       return gpg_error (GPG_ERR_INV_CERT_OBJ);
    1473             :     }
    1474           0 :   gcry_md_hash_buffer (GCRY_MD_SHA1, issuerhash, tmp, strlen (tmp));
    1475           0 :   xfree (tmp);
    1476           0 :   for (i=0,tmp=issuerhash_hex; i < 20; i++, tmp += 2)
    1477           0 :     sprintf (tmp, "%02X", issuerhash[i]);
    1478             : 
    1479             :   /* Get the serial number.  */
    1480           0 :   serial = ksba_cert_get_serial (cert);
    1481           0 :   if (!serial)
    1482             :     {
    1483           0 :       log_error ("oops: S/N missing in certificate\n");
    1484           0 :       return gpg_error (GPG_ERR_INV_CERT_OBJ);
    1485             :     }
    1486           0 :   sn = serial;
    1487           0 :   if (*sn != '(')
    1488             :     {
    1489           0 :       log_error ("oops: invalid S/N\n");
    1490           0 :       xfree (serial);
    1491           0 :       return gpg_error (GPG_ERR_INV_CERT_OBJ);
    1492             :     }
    1493           0 :   sn++;
    1494           0 :   snlen = strtoul (sn, &endp, 10);
    1495           0 :   sn = endp;
    1496           0 :   if (*sn != ':')
    1497             :     {
    1498           0 :       log_error ("oops: invalid S/N\n");
    1499           0 :       xfree (serial);
    1500           0 :       return gpg_error (GPG_ERR_INV_CERT_OBJ);
    1501             :     }
    1502           0 :   sn++;
    1503             : 
    1504             :   /* Check the cache.  */
    1505           0 :   result = cache_isvalid (ctrl, issuerhash_hex, sn, snlen, force_refresh);
    1506           0 :   switch (result)
    1507             :     {
    1508             :     case CRL_CACHE_VALID:
    1509           0 :       err = 0;
    1510           0 :       break;
    1511             :     case CRL_CACHE_INVALID:
    1512           0 :       err = gpg_error (GPG_ERR_CERT_REVOKED);
    1513           0 :       break;
    1514             :     case CRL_CACHE_DONTKNOW:
    1515           0 :       err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
    1516           0 :       break;
    1517             :     case CRL_CACHE_CANTUSE:
    1518           0 :       err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
    1519           0 :       break;
    1520             :     default:
    1521           0 :       log_fatal ("cache_isvalid returned invalid status code %d\n", result);
    1522             :     }
    1523             : 
    1524           0 :   xfree (serial);
    1525           0 :   return err;
    1526             : }
    1527             : 
    1528             : 
    1529             : /* Prepare a hash context for the signature verification.  Input is
    1530             :    the CRL and the output is the hash context MD as well as the uses
    1531             :    algorithm identifier ALGO. */
    1532             : static gpg_error_t
    1533           0 : start_sig_check (ksba_crl_t crl, gcry_md_hd_t *md, int *algo)
    1534             : {
    1535             :   gpg_error_t err;
    1536             :   const char *algoid;
    1537             : 
    1538           0 :   algoid = ksba_crl_get_digest_algo (crl);
    1539           0 :   *algo = gcry_md_map_name (algoid);
    1540           0 :   if (!*algo)
    1541             :     {
    1542           0 :       log_error (_("unknown hash algorithm '%s'\n"), algoid? algoid:"?");
    1543           0 :       return gpg_error (GPG_ERR_DIGEST_ALGO);
    1544             :     }
    1545             : 
    1546           0 :   err = gcry_md_open (md, *algo, 0);
    1547           0 :   if (err)
    1548             :     {
    1549           0 :       log_error (_("gcry_md_open for algorithm %d failed: %s\n"),
    1550             :                  *algo, gcry_strerror (err));
    1551           0 :       return err;
    1552             :     }
    1553           0 :   if (DBG_HASHING)
    1554           0 :     gcry_md_debug (*md, "hash.cert");
    1555             : 
    1556           0 :   ksba_crl_set_hash_function (crl, HASH_FNC, *md);
    1557           0 :   return 0;
    1558             : }
    1559             : 
    1560             : 
    1561             : /* Finish a hash context and verify the signature.  This function
    1562             :    should return 0 on a good signature, GPG_ERR_BAD_SIGNATURE if the
    1563             :    signature does not verify or any other error code. CRL is the CRL
    1564             :    object we are working on, MD the hash context and ISSUER_CERT the
    1565             :    certificate of the CRL issuer.  This function closes MD.  */
    1566             : static gpg_error_t
    1567           0 : finish_sig_check (ksba_crl_t crl, gcry_md_hd_t md, int algo,
    1568             :                   ksba_cert_t issuer_cert)
    1569             : {
    1570             :   gpg_error_t err;
    1571           0 :   ksba_sexp_t sigval = NULL, pubkey = NULL;
    1572             :   const char *s;
    1573             :   char algoname[50];
    1574             :   size_t n;
    1575           0 :   gcry_sexp_t s_sig = NULL, s_hash = NULL, s_pkey = NULL;
    1576             :   unsigned int i;
    1577             : 
    1578             :   /* This also stops debugging on the MD.  */
    1579           0 :   gcry_md_final (md);
    1580             : 
    1581             :   /* Get and convert the signature value. */
    1582           0 :   sigval = ksba_crl_get_sig_val (crl);
    1583           0 :   n = gcry_sexp_canon_len (sigval, 0, NULL, NULL);
    1584           0 :   if (!n)
    1585             :     {
    1586           0 :       log_error (_("got an invalid S-expression from libksba\n"));
    1587           0 :       err = gpg_error (GPG_ERR_INV_SEXP);
    1588           0 :       goto leave;
    1589             :     }
    1590           0 :   err = gcry_sexp_sscan (&s_sig, NULL, sigval, n);
    1591           0 :   if (err)
    1592             :     {
    1593           0 :       log_error (_("converting S-expression failed: %s\n"),
    1594             :                  gcry_strerror (err));
    1595           0 :       goto leave;
    1596             :     }
    1597             : 
    1598             :   /* Get and convert the public key for the issuer certificate. */
    1599           0 :   if (DBG_X509)
    1600           0 :     dump_cert ("crl_issuer_cert", issuer_cert);
    1601           0 :   pubkey = ksba_cert_get_public_key (issuer_cert);
    1602           0 :   n = gcry_sexp_canon_len (pubkey, 0, NULL, NULL);
    1603           0 :   if (!n)
    1604             :     {
    1605           0 :       log_error (_("got an invalid S-expression from libksba\n"));
    1606           0 :       err = gpg_error (GPG_ERR_INV_SEXP);
    1607           0 :       goto leave;
    1608             :     }
    1609           0 :   err = gcry_sexp_sscan (&s_pkey, NULL, pubkey, n);
    1610           0 :   if (err)
    1611             :     {
    1612           0 :       log_error (_("converting S-expression failed: %s\n"),
    1613             :                  gcry_strerror (err));
    1614           0 :       goto leave;
    1615             :     }
    1616             : 
    1617             :   /* Create an S-expression with the actual hash value. */
    1618           0 :   s = gcry_md_algo_name (algo);
    1619           0 :   for (i = 0; *s && i < sizeof(algoname) - 1; s++, i++)
    1620           0 :     algoname[i] = ascii_tolower (*s);
    1621           0 :   algoname[i] = 0;
    1622           0 :   err = gcry_sexp_build (&s_hash, NULL, "(data(flags pkcs1)(hash %s %b))",
    1623             :                          algoname,
    1624             :                          gcry_md_get_algo_dlen (algo), gcry_md_read (md, algo));
    1625           0 :   if (err)
    1626             :     {
    1627           0 :       log_error (_("creating S-expression failed: %s\n"), gcry_strerror (err));
    1628           0 :       goto leave;
    1629             :     }
    1630             : 
    1631             :   /* Pass this on to the signature verification. */
    1632           0 :   err = gcry_pk_verify (s_sig, s_hash, s_pkey);
    1633           0 :   if (DBG_X509)
    1634           0 :     log_debug ("gcry_pk_verify: %s\n", gpg_strerror (err));
    1635             : 
    1636             :  leave:
    1637           0 :   xfree (sigval);
    1638           0 :   xfree (pubkey);
    1639           0 :   gcry_sexp_release (s_sig);
    1640           0 :   gcry_sexp_release (s_hash);
    1641           0 :   gcry_sexp_release (s_pkey);
    1642           0 :   gcry_md_close (md);
    1643             : 
    1644           0 :   return err;
    1645             : }
    1646             : 
    1647             : 
    1648             : /* Call this to match a start_sig_check that can not be completed
    1649             :    normally.  */
    1650             : static void
    1651           0 : abort_sig_check (ksba_crl_t crl, gcry_md_hd_t md)
    1652             : {
    1653             :   (void)crl;
    1654           0 :   gcry_md_close (md);
    1655           0 : }
    1656             : 
    1657             : 
    1658             : /* Workhorse of the CRL loading machinery.  The CRL is read using the
    1659             :    CRL object and stored in the data base file DB with the name FNAME
    1660             :    (only used for printing error messages).  That DB should be a
    1661             :    temporary one and not the actual one.  If the function fails the
    1662             :    caller should delete this temporary database file.  CTRL is
    1663             :    required to retrieve certificates using the general dirmngr
    1664             :    callback service.  R_CRLISSUER returns an allocated string with the
    1665             :    crl-issuer DN, THIS_UPDATE and NEXT_UPDATE are filled with the
    1666             :    corresponding data from the CRL.  Note that these values might get
    1667             :    set even if the CRL processing fails at a later step; thus the
    1668             :    caller should free *R_ISSUER even if the function returns with an
    1669             :    error.  R_TRUST_ANCHOR is set on exit to NULL or a string with the
    1670             :    hexified fingerprint of the root certificate, if checking this
    1671             :    certificate for trustiness is required.
    1672             : */
    1673             : static int
    1674           0 : crl_parse_insert (ctrl_t ctrl, ksba_crl_t crl,
    1675             :                   struct cdb_make *cdb, const char *fname,
    1676             :                   char **r_crlissuer,
    1677             :                   ksba_isotime_t thisupdate, ksba_isotime_t nextupdate,
    1678             :                   char **r_trust_anchor)
    1679             : {
    1680             :   gpg_error_t err;
    1681             :   ksba_stop_reason_t stopreason;
    1682           0 :   ksba_cert_t crlissuer_cert = NULL;
    1683           0 :   gcry_md_hd_t md = NULL;
    1684           0 :   int algo = 0;
    1685             :   size_t n;
    1686             : 
    1687             :   (void)fname;
    1688             : 
    1689           0 :   *r_crlissuer = NULL;
    1690           0 :   *thisupdate = *nextupdate = 0;
    1691           0 :   *r_trust_anchor = NULL;
    1692             : 
    1693             :   /* Start of the KSBA parser loop. */
    1694             :   do
    1695             :     {
    1696           0 :       err = ksba_crl_parse (crl, &stopreason);
    1697           0 :       if (err)
    1698             :         {
    1699           0 :           log_error (_("ksba_crl_parse failed: %s\n"), gpg_strerror (err) );
    1700           0 :           goto failure;
    1701             :         }
    1702             : 
    1703           0 :       switch (stopreason)
    1704             :         {
    1705             :         case KSBA_SR_BEGIN_ITEMS:
    1706             :           {
    1707           0 :             err = start_sig_check (crl, &md, &algo);
    1708           0 :             if (err)
    1709           0 :               goto failure;
    1710             : 
    1711           0 :             err = ksba_crl_get_update_times (crl, thisupdate, nextupdate);
    1712           0 :             if (err)
    1713             :               {
    1714           0 :                 log_error (_("error getting update times of CRL: %s\n"),
    1715             :                            gpg_strerror (err));
    1716           0 :                 err = gpg_error (GPG_ERR_INV_CRL);
    1717           0 :                 goto failure;
    1718             :               }
    1719             : 
    1720           0 :             if (opt.verbose || !*nextupdate)
    1721           0 :               log_info (_("update times of this CRL: this=%s next=%s\n"),
    1722             :                         thisupdate, nextupdate);
    1723           0 :             if (!*nextupdate)
    1724             :               {
    1725           0 :                 log_info (_("nextUpdate not given; "
    1726             :                             "assuming a validity period of one day\n"));
    1727           0 :                 gnupg_copy_time (nextupdate, thisupdate);
    1728           0 :                 add_seconds_to_isotime (nextupdate, 86400);
    1729             :               }
    1730             :           }
    1731           0 :           break;
    1732             : 
    1733             :         case KSBA_SR_GOT_ITEM:
    1734             :           {
    1735             :             ksba_sexp_t serial;
    1736             :             const unsigned char *p;
    1737             :             ksba_isotime_t rdate;
    1738             :             ksba_crl_reason_t reason;
    1739             :             int rc;
    1740             :             unsigned char record[1+15];
    1741             : 
    1742           0 :             err = ksba_crl_get_item (crl, &serial, rdate, &reason);
    1743           0 :             if (err)
    1744             :               {
    1745           0 :                 log_error (_("error getting CRL item: %s\n"),
    1746             :                            gpg_strerror (err));
    1747           0 :                 err = gpg_error (GPG_ERR_INV_CRL);
    1748           0 :                 ksba_free (serial);
    1749           0 :                 goto failure;
    1750             :               }
    1751           0 :             p = serial_to_buffer (serial, &n);
    1752           0 :             if (!p)
    1753           0 :               BUG ();
    1754           0 :             record[0] = (reason & 0xff);
    1755           0 :             memcpy (record+1, rdate, 15);
    1756           0 :             rc = cdb_make_add (cdb, p, n, record, 1+15);
    1757           0 :             if (rc)
    1758             :               {
    1759           0 :                 err = gpg_error_from_errno (errno);
    1760           0 :                 log_error (_("error inserting item into "
    1761             :                              "temporary cache file: %s\n"),
    1762           0 :                            strerror (errno));
    1763           0 :                 goto failure;
    1764             :               }
    1765             : 
    1766           0 :             ksba_free (serial);
    1767             :           }
    1768           0 :           break;
    1769             : 
    1770             :         case KSBA_SR_END_ITEMS:
    1771           0 :           break;
    1772             : 
    1773             :         case KSBA_SR_READY:
    1774             :           {
    1775             :             char *crlissuer;
    1776             :             ksba_name_t authid;
    1777             :             ksba_sexp_t authidsn;
    1778             :             ksba_sexp_t keyid;
    1779             : 
    1780             :             /* We need to look for the issuer only after having read
    1781             :                all items.  The issuer itselfs comes before the items
    1782             :                but the optional authorityKeyIdentifier comes after the
    1783             :                items. */
    1784           0 :             err = ksba_crl_get_issuer (crl, &crlissuer);
    1785           0 :             if( err )
    1786             :               {
    1787           0 :                 log_error (_("no CRL issuer found in CRL: %s\n"),
    1788             :                            gpg_strerror (err) );
    1789           0 :                 err = gpg_error (GPG_ERR_INV_CRL);
    1790           0 :                 goto failure;
    1791             :               }
    1792             :             /* Note: This should be released by ksba_free, not xfree.
    1793             :                May need a memory reallocation dance.  */
    1794           0 :             *r_crlissuer = crlissuer; /* (Do it here so we don't need
    1795             :                                          to free it later) */
    1796             : 
    1797           0 :             if (!ksba_crl_get_auth_key_id (crl, &keyid, &authid, &authidsn))
    1798             :               {
    1799             :                 const char *s;
    1800             : 
    1801           0 :                 if (opt.verbose)
    1802           0 :                   log_info (_("locating CRL issuer certificate by "
    1803             :                               "authorityKeyIdentifier\n"));
    1804             : 
    1805           0 :                 s = ksba_name_enum (authid, 0);
    1806           0 :                 if (s && *authidsn)
    1807           0 :                   crlissuer_cert = find_cert_bysn (ctrl, s, authidsn);
    1808           0 :                 if (!crlissuer_cert && keyid)
    1809           0 :                   crlissuer_cert = find_cert_bysubject (ctrl,
    1810             :                                                         crlissuer, keyid);
    1811             : 
    1812           0 :                 if (!crlissuer_cert)
    1813             :                   {
    1814           0 :                     log_info ("CRL issuer certificate ");
    1815           0 :                     if (keyid)
    1816             :                       {
    1817           0 :                         log_printf ("{");
    1818           0 :                         dump_serial (keyid);
    1819           0 :                         log_printf ("} ");
    1820             :                       }
    1821           0 :                     if (authidsn)
    1822             :                       {
    1823           0 :                         log_printf ("(#");
    1824           0 :                         dump_serial (authidsn);
    1825           0 :                         log_printf ("/");
    1826           0 :                         dump_string (s);
    1827           0 :                         log_printf (") ");
    1828             :                       }
    1829           0 :                     log_printf ("not found\n");
    1830             :                   }
    1831           0 :                 ksba_name_release (authid);
    1832           0 :                 xfree (authidsn);
    1833           0 :                 xfree (keyid);
    1834             :               }
    1835             :             else
    1836           0 :               crlissuer_cert = find_cert_bysubject (ctrl, crlissuer, NULL);
    1837           0 :             err = 0;
    1838           0 :             if (!crlissuer_cert)
    1839             :               {
    1840           0 :                 err = gpg_error (GPG_ERR_MISSING_CERT);
    1841           0 :                 goto failure;
    1842             :               }
    1843             : 
    1844           0 :             err = finish_sig_check (crl, md, algo, crlissuer_cert);
    1845           0 :             if (err)
    1846             :               {
    1847           0 :                 log_error (_("CRL signature verification failed: %s\n"),
    1848             :                            gpg_strerror (err));
    1849           0 :                 goto failure;
    1850             :               }
    1851           0 :             md = NULL;
    1852             : 
    1853           0 :             err = validate_cert_chain (ctrl, crlissuer_cert, NULL,
    1854             :                                        VALIDATE_MODE_CRL_RECURSIVE,
    1855             :                                        r_trust_anchor);
    1856           0 :             if (err)
    1857             :               {
    1858           0 :                 log_error (_("error checking validity of CRL "
    1859             :                              "issuer certificate: %s\n"),
    1860             :                            gpg_strerror (err));
    1861           0 :                 goto failure;
    1862             :               }
    1863             : 
    1864             :           }
    1865           0 :           break;
    1866             : 
    1867             :         default:
    1868           0 :           log_debug ("crl_parse_insert: unknown stop reason\n");
    1869           0 :           err = gpg_error (GPG_ERR_BUG);
    1870           0 :           goto failure;
    1871             :         }
    1872             :     }
    1873           0 :   while (stopreason != KSBA_SR_READY);
    1874           0 :   assert (!err);
    1875             : 
    1876             : 
    1877             :  failure:
    1878           0 :   if (md)
    1879           0 :     abort_sig_check (crl, md);
    1880           0 :   ksba_cert_release (crlissuer_cert);
    1881           0 :   return err;
    1882             : }
    1883             : 
    1884             : 
    1885             : 
    1886             : /* Return the crlNumber extension as an allocated hex string or NULL
    1887             :    if there is none. */
    1888             : static char *
    1889           0 : get_crl_number (ksba_crl_t crl)
    1890             : {
    1891             :   gpg_error_t err;
    1892             :   ksba_sexp_t number;
    1893             :   char *string;
    1894             : 
    1895           0 :   err = ksba_crl_get_crl_number (crl, &number);
    1896           0 :   if (err)
    1897           0 :     return NULL;
    1898           0 :   string = serial_hex (number);
    1899           0 :   ksba_free (number);
    1900           0 :   return string;
    1901             : }
    1902             : 
    1903             : 
    1904             : /* Return the authorityKeyIdentifier or NULL if it is not available.
    1905             :    The issuer name may consists of several parts - they are delimted by
    1906             :    0x01. */
    1907             : static char *
    1908           0 : get_auth_key_id (ksba_crl_t crl, char **serialno)
    1909             : {
    1910             :   gpg_error_t err;
    1911             :   ksba_name_t name;
    1912             :   ksba_sexp_t sn;
    1913             :   int idx;
    1914             :   const char *s;
    1915             :   char *string;
    1916             :   size_t length;
    1917             : 
    1918           0 :   *serialno = NULL;
    1919           0 :   err = ksba_crl_get_auth_key_id (crl, NULL, &name, &sn);
    1920           0 :   if (err)
    1921           0 :     return NULL;
    1922           0 :   *serialno = serial_hex (sn);
    1923           0 :   ksba_free (sn);
    1924             : 
    1925           0 :   if (!name)
    1926           0 :     return xstrdup ("");
    1927             : 
    1928           0 :   length = 0;
    1929           0 :   for (idx=0; (s = ksba_name_enum (name, idx)); idx++)
    1930             :     {
    1931           0 :       char *p = ksba_name_get_uri (name, idx);
    1932           0 :       length += strlen (p?p:s) + 1;
    1933           0 :       xfree (p);
    1934             :     }
    1935           0 :   string = xtrymalloc (length+1);
    1936           0 :   if (string)
    1937             :     {
    1938           0 :       *string = 0;
    1939           0 :       for (idx=0; (s = ksba_name_enum (name, idx)); idx++)
    1940             :         {
    1941           0 :           char *p = ksba_name_get_uri (name, idx);
    1942           0 :           if (*string)
    1943           0 :             strcat (string, "\x01");
    1944           0 :           strcat (string, p?p:s);
    1945           0 :           xfree (p);
    1946             :         }
    1947             :     }
    1948           0 :   ksba_name_release (name);
    1949           0 :   return string;
    1950             : }
    1951             : 
    1952             : 
    1953             : 
    1954             : /* Insert the CRL retrieved using URL into the cache specified by
    1955             :    CACHE.  The CRL itself will be read from the stream FP and is
    1956             :    expected in binary format.
    1957             : 
    1958             :    Called by:
    1959             :       crl_cache_load
    1960             :          cmd_loadcrl
    1961             :          --load-crl
    1962             :       crl_cache_reload_crl
    1963             :          cmd_isvalid
    1964             :          cmd_checkcrl
    1965             :       cmd_loadcrl
    1966             :       --fetch-crl
    1967             : 
    1968             :  */
    1969             : gpg_error_t
    1970           0 : crl_cache_insert (ctrl_t ctrl, const char *url, ksba_reader_t reader)
    1971             : {
    1972           0 :   crl_cache_t cache = get_current_cache ();
    1973             :   gpg_error_t err, err2;
    1974             :   ksba_crl_t crl;
    1975           0 :   char *fname = NULL;
    1976           0 :   char *newfname = NULL;
    1977             :   struct cdb_make cdb;
    1978           0 :   int fd_cdb = -1;
    1979           0 :   char *issuer = NULL;
    1980           0 :   char *issuer_hash = NULL;
    1981             :   ksba_isotime_t thisupdate, nextupdate;
    1982           0 :   crl_cache_entry_t entry = NULL;
    1983             :   crl_cache_entry_t e;
    1984             :   gnupg_isotime_t current_time;
    1985           0 :   char *checksum = NULL;
    1986           0 :   int invalidate_crl = 0;
    1987             :   int idx;
    1988             :   const char *oid;
    1989             :   int critical;
    1990           0 :   char *trust_anchor = NULL;
    1991             : 
    1992             :   /* FIXME: We should acquire a mutex for the URL, so that we don't
    1993             :      simultaneously enter the same CRL twice.  However this needs to be
    1994             :      interweaved with the checking function.*/
    1995             : 
    1996           0 :   err2 = 0;
    1997             : 
    1998           0 :   err = ksba_crl_new (&crl);
    1999           0 :   if (err)
    2000             :     {
    2001           0 :       log_error (_("ksba_crl_new failed: %s\n"), gpg_strerror (err));
    2002           0 :       goto leave;
    2003             :     }
    2004             : 
    2005           0 :   err = ksba_crl_set_reader (crl, reader);
    2006           0 :   if ( err )
    2007             :     {
    2008           0 :       log_error (_("ksba_crl_set_reader failed: %s\n"), gpg_strerror (err));
    2009           0 :       goto leave;
    2010             :     }
    2011             : 
    2012             :   /* Create a temporary cache file to load the CRL into. */
    2013             :   {
    2014             :     char *tmpfname, *p;
    2015             :     const char *nodename;
    2016             : #ifndef HAVE_W32_SYSTEM
    2017             :     struct utsname utsbuf;
    2018             : #endif
    2019             : 
    2020             : #ifdef HAVE_W32_SYSTEM
    2021             :     nodename = "unknown";
    2022             : #else
    2023           0 :     if (uname (&utsbuf))
    2024           0 :       nodename = "unknown";
    2025             :     else
    2026           0 :       nodename = utsbuf.nodename;
    2027             : #endif
    2028             : 
    2029           0 :     gpgrt_asprintf (&tmpfname, "crl-tmp-%s-%u-%p.db.tmp",
    2030           0 :                     nodename, (unsigned int)getpid (), &tmpfname);
    2031           0 :     if (!tmpfname)
    2032             :       {
    2033           0 :         err = gpg_error_from_syserror ();
    2034           0 :         goto leave;
    2035             :       }
    2036           0 :     for (p=tmpfname; *p; p++)
    2037           0 :       if (*p == '/')
    2038           0 :         *p = '.';
    2039           0 :     fname = make_filename (opt.homedir_cache, DBDIR_D, tmpfname, NULL);
    2040           0 :     xfree (tmpfname);
    2041           0 :     if (!gnupg_remove (fname))
    2042           0 :       log_info (_("removed stale temporary cache file '%s'\n"), fname);
    2043           0 :     else if (errno != ENOENT)
    2044             :       {
    2045           0 :         err = gpg_error_from_syserror ();
    2046           0 :         log_error (_("problem removing stale temporary cache file '%s': %s\n"),
    2047             :                    fname, gpg_strerror (err));
    2048           0 :         goto leave;
    2049             :       }
    2050             :   }
    2051             : 
    2052           0 :   fd_cdb = open (fname, O_WRONLY | O_CREAT | O_TRUNC, 0644);
    2053           0 :   if (fd_cdb == -1)
    2054             :     {
    2055           0 :       err = gpg_error_from_errno (errno);
    2056           0 :       log_error (_("error creating temporary cache file '%s': %s\n"),
    2057           0 :                  fname, strerror (errno));
    2058           0 :       goto leave;
    2059             :     }
    2060           0 :   cdb_make_start(&cdb, fd_cdb);
    2061             : 
    2062           0 :   err = crl_parse_insert (ctrl, crl, &cdb, fname,
    2063             :                           &issuer, thisupdate, nextupdate, &trust_anchor);
    2064           0 :   if (err)
    2065             :     {
    2066           0 :       log_error (_("crl_parse_insert failed: %s\n"), gpg_strerror (err));
    2067             :       /* Error in cleanup ignored.  */
    2068           0 :       cdb_make_finish (&cdb);
    2069           0 :       goto leave;
    2070             :     }
    2071             : 
    2072             :   /* Finish the database. */
    2073           0 :   if (cdb_make_finish (&cdb))
    2074             :     {
    2075           0 :       err = gpg_error_from_errno (errno);
    2076           0 :       log_error (_("error finishing temporary cache file '%s': %s\n"),
    2077           0 :                  fname, strerror (errno));
    2078           0 :       goto leave;
    2079             :     }
    2080           0 :   if (close (fd_cdb))
    2081             :     {
    2082           0 :       err = gpg_error_from_errno (errno);
    2083           0 :       log_error (_("error closing temporary cache file '%s': %s\n"),
    2084           0 :                  fname, strerror (errno));
    2085           0 :       goto leave;
    2086             :     }
    2087           0 :   fd_cdb = -1;
    2088             : 
    2089             : 
    2090             :   /* Create a checksum. */
    2091             :   {
    2092             :     unsigned char md5buf[16];
    2093             : 
    2094           0 :     if (hash_dbfile (fname, md5buf))
    2095             :       {
    2096           0 :         err = gpg_error (GPG_ERR_CHECKSUM);
    2097           0 :         goto leave;
    2098             :       }
    2099           0 :     checksum = hexify_data (md5buf, 16, 0);
    2100             :   }
    2101             : 
    2102             : 
    2103             :   /* Check whether that new CRL is still not expired. */
    2104           0 :   gnupg_get_isotime (current_time);
    2105           0 :   if (strcmp (nextupdate, current_time) < 0 )
    2106             :     {
    2107           0 :       if (opt.force)
    2108           0 :         log_info (_("WARNING: new CRL still too old; it expired on %s "
    2109             :                     "- loading anyway\n"),  nextupdate);
    2110             :       else
    2111             :         {
    2112           0 :           log_error (_("new CRL still too old; it expired on %s\n"),
    2113             :                      nextupdate);
    2114           0 :           if (!err2)
    2115           0 :             err2 = gpg_error (GPG_ERR_CRL_TOO_OLD);
    2116           0 :           invalidate_crl |= 1;
    2117             :         }
    2118             :     }
    2119             : 
    2120             :   /* Check for unknown critical extensions. */
    2121           0 :   for (idx=0; !(err=ksba_crl_get_extension (crl, idx, &oid, &critical,
    2122           0 :                                               NULL, NULL)); idx++)
    2123             :     {
    2124           0 :       if (!critical
    2125           0 :           || !strcmp (oid, oidstr_authorityKeyIdentifier)
    2126           0 :           || !strcmp (oid, oidstr_crlNumber) )
    2127           0 :         continue;
    2128           0 :       log_error (_("unknown critical CRL extension %s\n"), oid);
    2129           0 :       if (!err2)
    2130           0 :         err2 = gpg_error (GPG_ERR_INV_CRL);
    2131           0 :       invalidate_crl |= 2;
    2132             :     }
    2133           0 :   if (gpg_err_code (err) == GPG_ERR_EOF
    2134           0 :       || gpg_err_code (err) == GPG_ERR_NO_DATA )
    2135           0 :     err = 0;
    2136           0 :   if (err)
    2137             :     {
    2138           0 :       log_error (_("error reading CRL extensions: %s\n"), gpg_strerror (err));
    2139           0 :       err = gpg_error (GPG_ERR_INV_CRL);
    2140             :     }
    2141             : 
    2142             : 
    2143             :   /* Create an hex encoded SHA-1 hash of the issuer DN to be
    2144             :      used as the key for the cache. */
    2145           0 :   issuer_hash = hashify_data (issuer, strlen (issuer));
    2146             : 
    2147             :   /* Create an ENTRY. */
    2148           0 :   entry = xtrycalloc (1, sizeof *entry);
    2149           0 :   if (!entry)
    2150             :     {
    2151           0 :       err = gpg_error_from_syserror ();
    2152           0 :       goto leave;
    2153             :     }
    2154           0 :   entry->release_ptr = xtrymalloc (strlen (issuer_hash) + 1
    2155             :                                    + strlen (issuer) + 1
    2156             :                                    + strlen (url) + 1
    2157             :                                    + strlen (checksum) + 1);
    2158           0 :   if (!entry->release_ptr)
    2159             :     {
    2160           0 :       err = gpg_error_from_syserror ();
    2161           0 :       xfree (entry);
    2162           0 :       entry = NULL;
    2163           0 :       goto leave;
    2164             :     }
    2165           0 :   entry->issuer_hash = entry->release_ptr;
    2166           0 :   entry->issuer = stpcpy (entry->issuer_hash, issuer_hash) + 1;
    2167           0 :   entry->url = stpcpy (entry->issuer, issuer) + 1;
    2168           0 :   entry->dbfile_hash = stpcpy (entry->url, url) + 1;
    2169           0 :   strcpy (entry->dbfile_hash, checksum);
    2170           0 :   gnupg_copy_time (entry->this_update, thisupdate);
    2171           0 :   gnupg_copy_time (entry->next_update, nextupdate);
    2172           0 :   gnupg_copy_time (entry->last_refresh, current_time);
    2173           0 :   entry->crl_number = get_crl_number (crl);
    2174           0 :   entry->authority_issuer = get_auth_key_id (crl, &entry->authority_serialno);
    2175           0 :   entry->invalid = invalidate_crl;
    2176           0 :   entry->user_trust_req = !!trust_anchor;
    2177           0 :   entry->check_trust_anchor = trust_anchor;
    2178           0 :   trust_anchor = NULL;
    2179             : 
    2180             :   /* Check whether we already have an entry for this issuer and mark
    2181             :      it as deleted. We better use a loop, just in case duplicates got
    2182             :      somehow into the list. */
    2183           0 :   for (e = cache->entries; (e=find_entry (e, entry->issuer_hash)); e = e->next)
    2184           0 :     e->deleted = 1;
    2185             : 
    2186             :   /* Rename the temporary DB to the real name. */
    2187           0 :   newfname = make_db_file_name (entry->issuer_hash);
    2188           0 :   if (opt.verbose)
    2189           0 :     log_info (_("creating cache file '%s'\n"), newfname);
    2190             : 
    2191             :   /* Just in case close unused matching files.  Actually we need this
    2192             :      only under Windows but saving file descriptors is never bad.  */
    2193             :   {
    2194             :     int any;
    2195             :     do
    2196             :       {
    2197           0 :         any = 0;
    2198           0 :         for (e = cache->entries; e; e = e->next)
    2199           0 :           if (!e->cdb_use_count && e->cdb
    2200           0 :               && !strcmp (e->issuer_hash, entry->issuer_hash))
    2201             :             {
    2202           0 :               int fd = cdb_fileno (e->cdb);
    2203           0 :               cdb_free (e->cdb);
    2204           0 :               xfree (e->cdb);
    2205           0 :               e->cdb = NULL;
    2206           0 :               if (close (fd))
    2207           0 :                 log_error (_("error closing cache file: %s\n"),
    2208           0 :                            strerror(errno));
    2209           0 :               any = 1;
    2210           0 :               break;
    2211             :             }
    2212             :       }
    2213           0 :     while (any);
    2214             :   }
    2215             : #ifdef HAVE_W32_SYSTEM
    2216             :   gnupg_remove (newfname);
    2217             : #endif
    2218           0 :   if (rename (fname, newfname))
    2219             :     {
    2220           0 :       err = gpg_error_from_syserror ();
    2221           0 :       log_error (_("problem renaming '%s' to '%s': %s\n"),
    2222             :                  fname, newfname, gpg_strerror (err));
    2223           0 :       goto leave;
    2224             :     }
    2225           0 :   xfree (fname); fname = NULL; /*(let the cleanup code not try to remove it)*/
    2226             : 
    2227             :   /* Link the new entry in. */
    2228           0 :   entry->next = cache->entries;
    2229           0 :   cache->entries = entry;
    2230           0 :   entry = NULL;
    2231             : 
    2232           0 :   err = update_dir (cache);
    2233           0 :   if (err)
    2234             :     {
    2235           0 :       log_error (_("updating the DIR file failed - "
    2236             :                    "cache entry will get lost with the next program start\n"));
    2237           0 :       err = 0; /* Keep on running. */
    2238             :     }
    2239             : 
    2240             : 
    2241             :  leave:
    2242           0 :   release_one_cache_entry (entry);
    2243           0 :   if (fd_cdb != -1)
    2244           0 :     close (fd_cdb);
    2245           0 :   if (fname)
    2246             :     {
    2247           0 :       gnupg_remove (fname);
    2248           0 :       xfree (fname);
    2249             :     }
    2250           0 :   xfree (newfname);
    2251           0 :   ksba_crl_release (crl);
    2252           0 :   xfree (issuer);
    2253           0 :   xfree (issuer_hash);
    2254           0 :   xfree (checksum);
    2255           0 :   xfree (trust_anchor);
    2256           0 :   return err ? err : err2;
    2257             : }
    2258             : 
    2259             : 
    2260             : /* Print one cached entry E in a human readable format to stream
    2261             :    FP. Return 0 on success. */
    2262             : static gpg_error_t
    2263           0 : list_one_crl_entry (crl_cache_t cache, crl_cache_entry_t e, estream_t fp)
    2264             : {
    2265             :   struct cdb_find cdbfp;
    2266             :   struct cdb *cdb;
    2267             :   int rc;
    2268           0 :   int warn = 0;
    2269             :   const unsigned char *s;
    2270             : 
    2271           0 :   es_fputs ("--------------------------------------------------------\n", fp );
    2272           0 :   es_fprintf (fp, _("Begin CRL dump (retrieved via %s)\n"), e->url );
    2273           0 :   es_fprintf (fp, " Issuer:\t%s\n", e->issuer );
    2274           0 :   es_fprintf (fp, " Issuer Hash:\t%s\n", e->issuer_hash );
    2275           0 :   es_fprintf (fp, " This Update:\t%s\n", e->this_update );
    2276           0 :   es_fprintf (fp, " Next Update:\t%s\n", e->next_update );
    2277           0 :   es_fprintf (fp, " CRL Number :\t%s\n", e->crl_number? e->crl_number: "none");
    2278           0 :   es_fprintf (fp, " AuthKeyId  :\t%s\n",
    2279           0 :               e->authority_serialno? e->authority_serialno:"none");
    2280           0 :   if (e->authority_serialno && e->authority_issuer)
    2281             :     {
    2282           0 :       es_fputs ("             \t", fp);
    2283           0 :       for (s=e->authority_issuer; *s; s++)
    2284           0 :         if (*s == '\x01')
    2285           0 :           es_fputs ("\n             \t", fp);
    2286             :         else
    2287           0 :           es_putc (*s, fp);
    2288           0 :       es_putc ('\n', fp);
    2289             :     }
    2290           0 :   es_fprintf (fp, " Trust Check:\t%s\n",
    2291           0 :               !e->user_trust_req? "[system]" :
    2292           0 :               e->check_trust_anchor? e->check_trust_anchor:"[missing]");
    2293             : 
    2294           0 :   if ((e->invalid & 1))
    2295           0 :     es_fprintf (fp, _(" ERROR: The CRL will not be used "
    2296             :                       "because it was still too old after an update!\n"));
    2297           0 :   if ((e->invalid & 2))
    2298           0 :     es_fprintf (fp, _(" ERROR: The CRL will not be used "
    2299             :                       "due to an unknown critical extension!\n"));
    2300           0 :   if ((e->invalid & ~3))
    2301           0 :     es_fprintf (fp, _(" ERROR: The CRL will not be used\n"));
    2302             : 
    2303           0 :   cdb = lock_db_file (cache, e);
    2304           0 :   if (!cdb)
    2305           0 :     return gpg_error (GPG_ERR_GENERAL);
    2306             : 
    2307           0 :   if (!e->dbfile_checked)
    2308           0 :     es_fprintf (fp, _(" ERROR: This cached CRL may have been tampered with!\n"));
    2309             : 
    2310           0 :   es_putc ('\n', fp);
    2311             : 
    2312           0 :   rc = cdb_findinit (&cdbfp, cdb, NULL, 0);
    2313           0 :   while (!rc && (rc=cdb_findnext (&cdbfp)) > 0 )
    2314             :     {
    2315             :       unsigned char keyrecord[256];
    2316             :       unsigned char record[16];
    2317             :       int reason;
    2318           0 :       int any = 0;
    2319             :       cdbi_t n;
    2320             :       cdbi_t i;
    2321             : 
    2322           0 :       rc = 0;
    2323           0 :       n = cdb_datalen (cdb);
    2324           0 :       if (n != 16)
    2325             :         {
    2326           0 :           log_error (_(" WARNING: invalid cache record length\n"));
    2327           0 :           warn = 1;
    2328           0 :           continue;
    2329             :         }
    2330             : 
    2331           0 :       if (cdb_read (cdb, record, n, cdb_datapos (cdb)))
    2332             :         {
    2333           0 :           log_error (_("problem reading cache record: %s\n"),
    2334           0 :                      strerror (errno));
    2335           0 :           warn = 1;
    2336           0 :           continue;
    2337             :         }
    2338             : 
    2339           0 :       n = cdb_keylen (cdb);
    2340           0 :       if (n > sizeof keyrecord)
    2341           0 :         n = sizeof keyrecord;
    2342           0 :       if (cdb_read (cdb, keyrecord, n, cdb_keypos (cdb)))
    2343             :         {
    2344           0 :           log_error (_("problem reading cache key: %s\n"), strerror (errno));
    2345           0 :           warn = 1;
    2346           0 :           continue;
    2347             :         }
    2348             : 
    2349           0 :       reason = *record;
    2350           0 :       es_fputs ("  ", fp);
    2351           0 :       for (i = 0; i < n; i++)
    2352           0 :         es_fprintf (fp, "%02X", keyrecord[i]);
    2353           0 :       es_fputs (":\t reasons( ", fp);
    2354             : 
    2355           0 :       if (reason & KSBA_CRLREASON_UNSPECIFIED)
    2356           0 :         es_fputs( "unspecified ", fp ), any = 1;
    2357           0 :       if (reason & KSBA_CRLREASON_KEY_COMPROMISE )
    2358           0 :         es_fputs( "key_compromise ", fp ), any = 1;
    2359           0 :       if (reason & KSBA_CRLREASON_CA_COMPROMISE )
    2360           0 :         es_fputs( "ca_compromise ", fp ), any = 1;
    2361           0 :       if (reason & KSBA_CRLREASON_AFFILIATION_CHANGED )
    2362           0 :         es_fputs( "affiliation_changed ", fp ), any = 1;
    2363           0 :       if (reason & KSBA_CRLREASON_SUPERSEDED )
    2364           0 :         es_fputs( "superseded", fp ), any = 1;
    2365           0 :       if (reason & KSBA_CRLREASON_CESSATION_OF_OPERATION )
    2366           0 :         es_fputs( "cessation_of_operation", fp ), any = 1;
    2367           0 :       if (reason & KSBA_CRLREASON_CERTIFICATE_HOLD )
    2368           0 :         es_fputs( "certificate_hold", fp ), any = 1;
    2369           0 :       if (reason && !any)
    2370           0 :         es_fputs( "other", fp );
    2371             : 
    2372           0 :       es_fprintf (fp, ") rdate: %.15s\n", record+1);
    2373             :     }
    2374           0 :   if (rc)
    2375           0 :     log_error (_("error reading cache entry from db: %s\n"), strerror (rc));
    2376             : 
    2377           0 :   unlock_db_file (cache, e);
    2378           0 :   es_fprintf (fp, _("End CRL dump\n") );
    2379           0 :   es_putc ('\n', fp);
    2380             : 
    2381           0 :   return (rc||warn)? gpg_error (GPG_ERR_GENERAL) : 0;
    2382             : }
    2383             : 
    2384             : 
    2385             : /* Print the contents of the CRL CACHE in a human readable format to
    2386             :    stream FP. */
    2387             : gpg_error_t
    2388           0 : crl_cache_list (estream_t fp)
    2389             : {
    2390           0 :   crl_cache_t cache = get_current_cache ();
    2391             :   crl_cache_entry_t entry;
    2392           0 :   gpg_error_t err = 0;
    2393             : 
    2394           0 :   for (entry = cache->entries;
    2395           0 :        entry && !entry->deleted && !err;
    2396           0 :        entry = entry->next )
    2397           0 :     err = list_one_crl_entry (cache, entry, fp);
    2398             : 
    2399           0 :   return err;
    2400             : }
    2401             : 
    2402             : 
    2403             : /* Load the CRL containing the file named FILENAME into our CRL cache. */
    2404             : gpg_error_t
    2405           0 : crl_cache_load (ctrl_t ctrl, const char *filename)
    2406             : {
    2407             :   gpg_error_t err;
    2408             :   estream_t fp;
    2409             :   ksba_reader_t reader;
    2410             : 
    2411           0 :   fp = es_fopen (filename, "r");
    2412           0 :   if (!fp)
    2413             :     {
    2414           0 :       err = gpg_error_from_errno (errno);
    2415           0 :       log_error (_("can't open '%s': %s\n"), filename, strerror (errno));
    2416           0 :       return err;
    2417             :     }
    2418             : 
    2419           0 :   err = create_estream_ksba_reader (&reader, fp);
    2420           0 :   if (!err)
    2421             :     {
    2422           0 :       err = crl_cache_insert (ctrl, filename, reader);
    2423           0 :       ksba_reader_release (reader);
    2424             :     }
    2425           0 :   es_fclose (fp);
    2426           0 :   return err;
    2427             : }
    2428             : 
    2429             : 
    2430             : /* Locate the corresponding CRL for the certificate CERT, read and
    2431             :    verify the CRL and store it in the cache.  */
    2432             : gpg_error_t
    2433           0 : crl_cache_reload_crl (ctrl_t ctrl, ksba_cert_t cert)
    2434             : {
    2435             :   gpg_error_t err;
    2436           0 :   ksba_reader_t reader = NULL;
    2437           0 :   char *issuer = NULL;
    2438           0 :   ksba_name_t distpoint = NULL;
    2439           0 :   ksba_name_t issuername = NULL;
    2440           0 :   char *distpoint_uri = NULL;
    2441           0 :   char *issuername_uri = NULL;
    2442           0 :   int any_dist_point = 0;
    2443             :   int seq;
    2444             : 
    2445             :   /* Loop over all distribution points, get the CRLs and put them into
    2446             :      the cache. */
    2447           0 :   if (opt.verbose)
    2448           0 :     log_info ("checking distribution points\n");
    2449           0 :   seq = 0;
    2450           0 :   while ( !(err = ksba_cert_get_crl_dist_point (cert, seq++,
    2451             :                                                 &distpoint,
    2452             :                                                 &issuername, NULL )))
    2453             :     {
    2454             :       int name_seq;
    2455           0 :       gpg_error_t last_err = 0;
    2456             : 
    2457           0 :       if (!distpoint && !issuername)
    2458             :         {
    2459           0 :           if (opt.verbose)
    2460           0 :             log_info ("no issuer name and no distribution point\n");
    2461           0 :           break; /* Not allowed; i.e. an invalid certificate.  We give
    2462             :                     up here and hope that the default method returns a
    2463             :                     suitable CRL. */
    2464             :         }
    2465             : 
    2466           0 :       xfree (issuername_uri); issuername_uri = NULL;
    2467             : 
    2468             :       /* Get the URIs.  We do this in a loop to iterate over all names
    2469             :          in the crlDP. */
    2470           0 :       for (name_seq=0; ksba_name_enum (distpoint, name_seq); name_seq++)
    2471             :         {
    2472           0 :           xfree (distpoint_uri); distpoint_uri = NULL;
    2473           0 :           distpoint_uri = ksba_name_get_uri (distpoint, name_seq);
    2474           0 :           if (!distpoint_uri)
    2475           0 :             continue;
    2476             : 
    2477           0 :           if (!strncmp (distpoint_uri, "ldap:", 5)
    2478           0 :               || !strncmp (distpoint_uri, "ldaps:", 6))
    2479             :             {
    2480           0 :               if (opt.ignore_ldap_dp)
    2481           0 :                 continue;
    2482             :             }
    2483           0 :           else if (!strncmp (distpoint_uri, "http:", 5)
    2484           0 :                    || !strncmp (distpoint_uri, "https:", 6))
    2485             :             {
    2486           0 :               if (opt.ignore_http_dp)
    2487           0 :                 continue;
    2488             :             }
    2489             :           else
    2490           0 :             continue; /* Skip unknown schemes. */
    2491             : 
    2492           0 :           any_dist_point = 1;
    2493             : 
    2494           0 :           if (opt.verbose)
    2495           0 :             log_info ("fetching CRL from '%s'\n", distpoint_uri);
    2496           0 :           err = crl_fetch (ctrl, distpoint_uri, &reader);
    2497           0 :           if (err)
    2498             :             {
    2499           0 :               log_error (_("crl_fetch via DP failed: %s\n"),
    2500             :                          gpg_strerror (err));
    2501           0 :               last_err = err;
    2502           0 :               continue; /* with the next name. */
    2503             :             }
    2504             : 
    2505           0 :           if (opt.verbose)
    2506           0 :             log_info ("inserting CRL (reader %p)\n", reader);
    2507           0 :           err = crl_cache_insert (ctrl, distpoint_uri, reader);
    2508           0 :           if (err)
    2509             :             {
    2510           0 :               log_error (_("crl_cache_insert via DP failed: %s\n"),
    2511             :                          gpg_strerror (err));
    2512           0 :               last_err = err;
    2513           0 :               continue; /* with the next name. */
    2514             :             }
    2515           0 :           last_err = 0;
    2516           0 :           break; /* Ready. */
    2517             :         }
    2518           0 :       if (last_err)
    2519             :         {
    2520           0 :           err = last_err;
    2521           0 :           goto leave;
    2522             :         }
    2523             : 
    2524           0 :       ksba_name_release (distpoint); distpoint = NULL;
    2525             : 
    2526             :       /* We don't do anything with issuername_uri yet but we keep the
    2527             :          code for documentation. */
    2528           0 :       issuername_uri =  ksba_name_get_uri (issuername, 0);
    2529           0 :       ksba_name_release (issuername); issuername = NULL;
    2530             : 
    2531             :       /* Close the reader.  */
    2532           0 :       crl_close_reader (reader);
    2533           0 :       reader = NULL;
    2534             :     }
    2535           0 :   if (gpg_err_code (err) == GPG_ERR_EOF)
    2536           0 :     err = 0;
    2537             : 
    2538             :   /* If we did not found any distpoint, try something reasonable. */
    2539           0 :   if (!any_dist_point )
    2540             :     {
    2541           0 :       if (opt.verbose)
    2542           0 :         log_info ("no distribution point - trying issuer name\n");
    2543             : 
    2544           0 :       crl_close_reader (reader);
    2545           0 :       reader = NULL;
    2546             : 
    2547           0 :       issuer = ksba_cert_get_issuer (cert, 0);
    2548           0 :       if (!issuer)
    2549             :         {
    2550           0 :           log_error ("oops: issuer missing in certificate\n");
    2551           0 :           err = gpg_error (GPG_ERR_INV_CERT_OBJ);
    2552           0 :           goto leave;
    2553             :         }
    2554             : 
    2555           0 :       if (opt.verbose)
    2556           0 :         log_info ("fetching CRL from default location\n");
    2557           0 :       err = crl_fetch_default (ctrl, issuer, &reader);
    2558           0 :       if (err)
    2559             :           {
    2560           0 :             log_error ("crl_fetch via issuer failed: %s\n",
    2561             :                        gpg_strerror (err));
    2562           0 :             goto leave;
    2563             :           }
    2564             : 
    2565           0 :       if (opt.verbose)
    2566           0 :         log_info ("inserting CRL (reader %p)\n", reader);
    2567           0 :       err = crl_cache_insert (ctrl, "default location(s)", reader);
    2568           0 :       if (err)
    2569             :         {
    2570           0 :           log_error (_("crl_cache_insert via issuer failed: %s\n"),
    2571             :                      gpg_strerror (err));
    2572           0 :           goto leave;
    2573             :         }
    2574             :     }
    2575             : 
    2576             :  leave:
    2577           0 :   crl_close_reader (reader);
    2578           0 :   xfree (distpoint_uri);
    2579           0 :   xfree (issuername_uri);
    2580           0 :   ksba_name_release (distpoint);
    2581           0 :   ksba_name_release (issuername);
    2582           0 :   ksba_free (issuer);
    2583           0 :   return err;
    2584             : }

Generated by: LCOV version 1.11