gpg: Remove PGP6 compliance mode.
[gnupg.git] / dirmngr / crlcache.c
index edf3837..fbe3bee 100644 (file)
@@ -15,7 +15,7 @@
  * GNU General Public License for more details.
  *
  * You should have received a copy of the GNU General Public License
- * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ * along with this program; if not, see <https://www.gnu.org/licenses/>.
  */
 
 /*
@@ -44,7 +44,7 @@
         Field 1: Constant "v"
         Field 2: Version number of this file.  Must be 1.
 
-        This record must be the first non-comment record record and
+        This record must be the first non-comment record and
         there shall only exist one record of this type.
 
    1.3. CRL cache record
 #include "crlfetch.h"
 #include "misc.h"
 #include "cdb.h"
-#include "estream-printf.h"
 
 /* Change this whenever the format changes */
-#define DBDIR_D (opt.system_daemon? "crls.d" : "dirmngr-cache.d")
+#define DBDIR_D "crls.d"
 #define DBDIRFILE "DIR.txt"
 #define DBDIRVERSION 1
 
    idea anyway to limit the number of opened cache files. */
 #define MAX_OPEN_DB_FILES 5
 
+#ifndef O_BINARY
+# define O_BINARY 0
+#endif
 
 static const char oidstr_crlNumber[] = "2.5.29.20";
-static const char oidstr_issuingDistributionPoint[] = "2.5.29.28";
+/* static const char oidstr_issuingDistributionPoint[] = "2.5.29.28"; */
 static const char oidstr_authorityKeyIdentifier[] = "2.5.29.35";
 
 
@@ -211,11 +213,11 @@ create_directory_if_needed (const char *name)
   dir = opendir (fname);
   if (!dir)
     {
-      log_info (_("creating directory `%s'\n"), fname);
+      log_info (_("creating directory '%s'\n"), fname);
       if (mkdir (fname, S_IRUSR|S_IWUSR|S_IXUSR) )
         {
           int save_errno = errno;
-          log_error (_("error creating directory `%s': %s\n"),
+          log_error (_("error creating directory '%s': %s\n"),
                      fname, strerror (errno));
           xfree (fname);
           gpg_err_set_errno (save_errno);
@@ -243,7 +245,7 @@ cleanup_cache_dir (int force)
     { /* Very minor sanity checks. */
       if (!strcmp (dname, "~/") || !strcmp (dname, "/" ))
         {
-          log_error (_("ignoring database dir `%s'\n"), dname);
+          log_error (_("ignoring database dir '%s'\n"), dname);
           xfree (dname);
           return -1;
         }
@@ -252,7 +254,7 @@ cleanup_cache_dir (int force)
   dir = opendir (dname);
   if (!dir)
     {
-      log_error (_("error reading directory `%s': %s\n"),
+      log_error (_("error reading directory '%s': %s\n"),
                  dname, strerror (errno));
       xfree (dname);
       return -1;
@@ -273,16 +275,16 @@ cleanup_cache_dir (int force)
 
           if (okay)
             {
-              log_info (_("removing cache file `%s'\n"), cdbname);
+              log_info (_("removing cache file '%s'\n"), cdbname);
               if (gnupg_remove (cdbname))
                 {
-                  log_error ("failed to remove `%s': %s\n",
+                  log_error ("failed to remove '%s': %s\n",
                              cdbname, strerror (errno));
                   problem = -1;
                 }
             }
           else
-            log_info (_("not removing file `%s'\n"), cdbname);
+            log_info (_("not removing file '%s'\n"), cdbname);
           xfree (cdbname);
         }
     }
@@ -409,7 +411,7 @@ open_dir_file (const char *fname)
   fp = es_fopen (fname, "r");
   if (!fp)
     {
-      log_error (_("failed to open cache dir file `%s': %s\n"),
+      log_error (_("failed to open cache dir file '%s': %s\n"),
                  fname, strerror (errno));
 
       /* Make sure that the directory exists, try to create if otherwise. */
@@ -419,31 +421,31 @@ open_dir_file (const char *fname)
       fp = es_fopen (fname, "w");
       if (!fp)
         {
-          log_error (_("error creating new cache dir file `%s': %s\n"),
+          log_error (_("error creating new cache dir file '%s': %s\n"),
                      fname, strerror (errno));
           return NULL;
         }
       es_fprintf (fp, "v:%d:\n", DBDIRVERSION);
       if (es_ferror (fp))
         {
-          log_error (_("error writing new cache dir file `%s': %s\n"),
+          log_error (_("error writing new cache dir file '%s': %s\n"),
                      fname, strerror (errno));
           es_fclose (fp);
           return NULL;
         }
       if (es_fclose (fp))
         {
-          log_error (_("error closing new cache dir file `%s': %s\n"),
+          log_error (_("error closing new cache dir file '%s': %s\n"),
                      fname, strerror (errno));
           return NULL;
         }
 
-      log_info (_("new cache dir file `%s' created\n"), fname);
+      log_info (_("new cache dir file '%s' created\n"), fname);
 
       fp = es_fopen (fname, "r");
       if (!fp)
         {
-          log_error (_("failed to re-open cache dir file `%s': %s\n"),
+          log_error (_("failed to re-open cache dir file '%s': %s\n"),
                      fname, strerror (errno));
           return NULL;
         }
@@ -471,7 +473,7 @@ check_dir_version (estream_t *fpadr, const char *fname,
         break;
       else if (*line != '#')
         {
-          log_error (_("first record of `%s' is not the version\n"), fname);
+          log_error (_("first record of '%s' is not the version\n"), fname);
           xfree (line);
           return gpg_error (GPG_ERR_CONFIGURATION);
         }
@@ -480,7 +482,9 @@ check_dir_version (estream_t *fpadr, const char *fname,
   if (lineerr)
     return lineerr;
 
-  if (strtol (line+2, NULL, 10) != DBDIRVERSION)
+  /* The !line catches the case of an empty DIR file.  We handle this
+     the same as a non-matching version.  */
+  if (!line || strtol (line+2, NULL, 10) != DBDIRVERSION)
     {
       if (!created && cleanup_on_mismatch)
         {
@@ -587,8 +591,14 @@ open_dir (crl_cache_t *r_cache)
                 case 2: entry->issuer_hash = p; break;
                 case 3: entry->issuer = unpercent_string (p); break;
                 case 4: entry->url = unpercent_string (p); break;
-                case 5: strncpy (entry->this_update, p, 15); break;
-                case 6: strncpy (entry->next_update, p, 15); break;
+                case 5:
+                 strncpy (entry->this_update, p, 15);
+                 entry->this_update[15] = 0;
+                 break;
+                case 6:
+                 strncpy (entry->next_update, p, 15);
+                 entry->next_update[15] = 0;
+                 break;
                 case 7: entry->dbfile_hash = p; break;
                 case 8: if (*p) entry->crl_number = p; break;
                 case 9:
@@ -606,14 +616,14 @@ open_dir (crl_cache_t *r_cache)
                 default:
                   if (*p)
                     log_info (_("extra field detected in crl record of "
-                                "`%s' line %u\n"), fname, lineno);
+                                "'%s' line %u\n"), fname, lineno);
                   break;
                 }
             }
 
           if (!entry->issuer_hash)
             {
-              log_info (_("invalid line detected in `%s' line %u\n"),
+              log_info (_("invalid line detected in '%s' line %u\n"),
                         fname, lineno);
               xfree (entry);
               entry = NULL;
@@ -622,7 +632,7 @@ open_dir (crl_cache_t *r_cache)
             {
               /* Fixme: The duplicate checking used is not very
                  effective for large numbers of issuers. */
-              log_info (_("duplicate entry detected in `%s' line %u\n"),
+              log_info (_("duplicate entry detected in '%s' line %u\n"),
                         fname, lineno);
               xfree (entry);
               entry = NULL;
@@ -637,7 +647,7 @@ open_dir (crl_cache_t *r_cache)
       else if (*line == '#')
         ;
       else
-        log_info (_("unsupported record type in `%s' line %u skipped\n"),
+        log_info (_("unsupported record type in '%s' line %u skipped\n"),
                   fname, lineno);
 
       if (line)
@@ -646,12 +656,12 @@ open_dir (crl_cache_t *r_cache)
   if (lineerr)
     {
       err = lineerr;
-      log_error (_("error reading `%s': %s\n"), fname, gpg_strerror (err));
+      log_error (_("error reading '%s': %s\n"), fname, gpg_strerror (err));
       goto leave;
     }
   if (es_ferror (fp))
     {
-      log_error (_("error reading `%s': %s\n"), fname, strerror (errno));
+      log_error (_("error reading '%s': %s\n"), fname, strerror (errno));
       err = gpg_error (GPG_ERR_CONFIGURATION);
       goto leave;
     }
@@ -663,26 +673,26 @@ open_dir (crl_cache_t *r_cache)
       if (strlen (entry->issuer_hash) != 40)
         {
           anyerr++;
-          log_error (_("invalid issuer hash in `%s' line %u\n"),
+          log_error (_("invalid issuer hash in '%s' line %u\n"),
                      fname, entry->lineno);
         }
       else if ( !*entry->issuer )
         {
           anyerr++;
-          log_error (_("no issuer DN in `%s' line %u\n"),
+          log_error (_("no issuer DN in '%s' line %u\n"),
                      fname, entry->lineno);
         }
       else if ( check_isotime (entry->this_update)
                 || check_isotime (entry->next_update))
         {
           anyerr++;
-          log_error (_("invalid timestamp in `%s' line %u\n"),
+          log_error (_("invalid timestamp in '%s' line %u\n"),
                      fname, entry->lineno);
         }
 
       /* Checks not leading to an immediate fail. */
       if (strlen (entry->dbfile_hash) != 32)
-        log_info (_("WARNING: invalid cache file hash in `%s' line %u\n"),
+        log_info (_("WARNING: invalid cache file hash in '%s' line %u\n"),
                   fname, entry->lineno);
     }
 
@@ -785,7 +795,7 @@ update_dir (crl_cache_t cache)
   if (!fp)
     {
       err = gpg_error_from_errno (errno);
-      log_error (_("failed to open cache dir file `%s': %s\n"),
+      log_error (_("failed to open cache dir file '%s': %s\n"),
                  fname, strerror (errno));
       goto leave;
     }
@@ -812,12 +822,12 @@ update_dir (crl_cache_t cache)
       nodename = utsbuf.nodename;
 #endif
 
-    estream_asprintf (&tmpbuf, "DIR-tmp-%s-%u-%p.txt.tmp",
-                      nodename, (unsigned int)getpid (), &tmpbuf);
+    gpgrt_asprintf (&tmpbuf, "DIR-tmp-%s-%u-%p.txt.tmp",
+                    nodename, (unsigned int)getpid (), &tmpbuf);
     if (!tmpbuf)
       {
         err = gpg_error_from_errno (errno);
-        log_error (_("failed to create temporary cache dir file `%s': %s\n"),
+        log_error (_("failed to create temporary cache dir file '%s': %s\n"),
                    tmpfname, strerror (errno));
         goto leave;
       }
@@ -831,7 +841,7 @@ update_dir (crl_cache_t cache)
   if (!fpout)
     {
       err = gpg_error_from_errno (errno);
-      log_error (_("failed to create temporary cache dir file `%s': %s\n"),
+      log_error (_("failed to create temporary cache dir file '%s': %s\n"),
                  tmpfname, strerror (errno));
       goto leave;
     }
@@ -852,7 +862,7 @@ update_dir (crl_cache_t cache)
                  field, thus we can compare it pretty easily. */
               *endp = 0;
               e = find_entry ( cache->entries, fieldp);
-              *endp = ':'; /* Restore orginal line. */
+              *endp = ':'; /* Restore original line. */
               if (e && e->deleted)
                 {
                   /* Marked for deletion, so don't write it. */
@@ -905,18 +915,18 @@ update_dir (crl_cache_t cache)
   if (lineerr)
     {
       err = lineerr;
-      log_error (_("error reading `%s': %s\n"), fname, gpg_strerror (err));
+      log_error (_("error reading '%s': %s\n"), fname, gpg_strerror (err));
       goto leave;
     }
   if (es_ferror (fp))
     {
       err = gpg_error_from_errno (errno);
-      log_error (_("error reading `%s': %s\n"), fname, strerror (errno));
+      log_error (_("error reading '%s': %s\n"), fname, strerror (errno));
     }
   if (es_ferror (fpout))
     {
       err = gpg_error_from_errno (errno);
-      log_error (_("error writing `%s': %s\n"), tmpfname, strerror (errno));
+      log_error (_("error writing '%s': %s\n"), tmpfname, strerror (errno));
     }
   if (err)
     goto leave;
@@ -927,7 +937,7 @@ update_dir (crl_cache_t cache)
   if (es_fclose (fpout))
     {
       err = gpg_error_from_errno (errno);
-      log_error (_("error closing `%s': %s\n"), tmpfname, strerror (errno));
+      log_error (_("error closing '%s': %s\n"), tmpfname, strerror (errno));
       goto leave;
     }
   fpout = NULL;
@@ -939,7 +949,7 @@ update_dir (crl_cache_t cache)
   if (rename (tmpfname, fname))
     {
       err = gpg_error_from_errno (errno);
-      log_error (_("error renaming `%s' to `%s': %s\n"),
+      log_error (_("error renaming '%s' to '%s': %s\n"),
                  tmpfname, fname, strerror (errno));
       goto leave;
     }
@@ -987,13 +997,13 @@ hash_dbfile (const char *fname, unsigned char *md5buffer)
   char *buffer;
   size_t n;
   gcry_md_hd_t md5;
-  gpg_err_code_t err;
+  gpg_error_t err;
 
   buffer = xtrymalloc (65536);
   fp = buffer? es_fopen (fname, "rb") : NULL;
   if (!fp)
     {
-      log_error (_("can't hash `%s': %s\n"), fname, strerror (errno));
+      log_error (_("can't hash '%s': %s\n"), fname, strerror (errno));
       xfree (buffer);
       return -1;
     }
@@ -1017,7 +1027,7 @@ hash_dbfile (const char *fname, unsigned char *md5buffer)
       n = es_fread (buffer, 1, 65536, fp);
       if (n < 65536 && es_ferror (fp))
         {
-          log_error (_("error hashing `%s': %s\n"), fname, strerror (errno));
+          log_error (_("error hashing '%s': %s\n"), fname, strerror (errno));
           xfree (buffer);
           es_fclose (fp);
           gcry_md_close (md5);
@@ -1045,7 +1055,7 @@ check_dbfile (const char *fname, const char *md5hexvalue)
 
   if (strlen (md5hexvalue) != 32)
     {
-      log_error (_("invalid formatted checksum for `%s'\n"), fname);
+      log_error (_("invalid formatted checksum for '%s'\n"), fname);
       return -1;
     }
   unhexify (buffer1, md5hexvalue);
@@ -1116,7 +1126,7 @@ lock_db_file (crl_cache_t cache, crl_cache_entry_t entry)
 
   fname = make_db_file_name (entry->issuer_hash);
   if (opt.verbose)
-    log_info (_("opening cache file `%s'\n"), fname );
+    log_info (_("opening cache file '%s'\n"), fname );
 
   if (!entry->dbfile_checked)
     {
@@ -1132,10 +1142,10 @@ lock_db_file (crl_cache_t cache, crl_cache_entry_t entry)
       xfree (fname);
       return NULL;
     }
-  fd = open (fname, O_RDONLY);
+  fd = open (fname, O_RDONLY | O_BINARY);
   if (fd == -1)
     {
-      log_error (_("error opening cache file `%s': %s\n"),
+      log_error (_("error opening cache file '%s': %s\n"),
                  fname, strerror (errno));
       xfree (entry->cdb);
       entry->cdb = NULL;
@@ -1144,7 +1154,7 @@ lock_db_file (crl_cache_t cache, crl_cache_entry_t entry)
     }
   if (cdb_init (entry->cdb, fd))
     {
-      log_error (_("error initializing cache file `%s' for reading: %s\n"),
+      log_error (_("error initializing cache file '%s' for reading: %s\n"),
                  fname, strerror (errno));
       xfree (entry->cdb);
       entry->cdb = NULL;
@@ -1205,7 +1215,7 @@ find_entry (crl_cache_entry_t first, const char *issuer_hash)
 }
 
 
-/* Create a new CRL cache. This fucntion is usually called only once.
+/* Create a new CRL cache. This function is usually called only once.
    never fail. */
 void
 crl_cache_init(void)
@@ -1338,12 +1348,13 @@ cache_isvalid (ctrl_t ctrl, const char *issuer_hash,
       if (n != 16)
         {
           log_error (_("WARNING: invalid cache record length for S/N "));
-          log_printhex ("", sn, snlen);
+          log_printf ("0x");
+          log_printhex (sn, snlen, "");
         }
       else if (opt.verbose)
         {
           unsigned char record[16];
-          char *tmp = hexify_data (sn, snlen);
+          char *tmp = hexify_data (sn, snlen, 1);
 
           if (cdb_read (cdb, record, n, cdb_datapos (cdb)))
             log_error (_("problem reading cache record for S/N %s: %s\n"),
@@ -1359,7 +1370,7 @@ cache_isvalid (ctrl_t ctrl, const char *issuer_hash,
     {
       if (opt.verbose)
         {
-          char *serialno = hexify_data (sn, snlen);
+          char *serialno = hexify_data (sn, snlen, 1);
           log_info (_("S/N %s is valid, it is not listed in the CRL\n"),
                     serialno );
           xfree (serialno);
@@ -1505,6 +1516,7 @@ crl_cache_cert_isvalid (ctrl_t ctrl, ksba_cert_t cert,
       break;
     case CRL_CACHE_DONTKNOW:
       err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
+      break;
     case CRL_CACHE_CANTUSE:
       err = gpg_error (GPG_ERR_NO_CRL_KNOWN);
       break;
@@ -1530,7 +1542,7 @@ start_sig_check (ksba_crl_t crl, gcry_md_hd_t *md, int *algo)
   *algo = gcry_md_map_name (algoid);
   if (!*algo)
     {
-      log_error (_("unknown hash algorithm `%s'\n"), algoid? algoid:"?");
+      log_error (_("unknown hash algorithm '%s'\n"), algoid? algoid:"?");
       return gpg_error (GPG_ERR_DIGEST_ALGO);
     }
 
@@ -1553,7 +1565,7 @@ start_sig_check (ksba_crl_t crl, gcry_md_hd_t *md, int *algo)
    should return 0 on a good signature, GPG_ERR_BAD_SIGNATURE if the
    signature does not verify or any other error code. CRL is the CRL
    object we are working on, MD the hash context and ISSUER_CERT the
-   certificate of the CRL issuer.  This function closes MD.  */
+   certificate of the CRL issuer.  This function takes ownership of MD.  */
 static gpg_error_t
 finish_sig_check (ksba_crl_t crl, gcry_md_hd_t md, int algo,
                   ksba_cert_t issuer_cert)
@@ -1637,12 +1649,13 @@ finish_sig_check (ksba_crl_t crl, gcry_md_hd_t md, int algo,
 
 
 /* Call this to match a start_sig_check that can not be completed
-   normally.  */
+   normally.  Takes ownership of MD if MD is not NULL.  */
 static void
 abort_sig_check (ksba_crl_t crl, gcry_md_hd_t md)
 {
   (void)crl;
-  gcry_md_close (md);
+  if (md)
+    gcry_md_close (md);
 }
 
 
@@ -1695,7 +1708,8 @@ crl_parse_insert (ctrl_t ctrl, ksba_crl_t crl,
         {
         case KSBA_SR_BEGIN_ITEMS:
           {
-            if (start_sig_check (crl, &md, &algo ))
+            err = start_sig_check (crl, &md, &algo);
+            if (err)
               goto failure;
 
             err = ksba_crl_get_update_times (crl, thisupdate, nextupdate);
@@ -1832,16 +1846,18 @@ crl_parse_insert (ctrl_t ctrl, ksba_crl_t crl,
               }
 
             err = finish_sig_check (crl, md, algo, crlissuer_cert);
+            md = NULL; /* Closed.  */
             if (err)
               {
                 log_error (_("CRL signature verification failed: %s\n"),
                            gpg_strerror (err));
                 goto failure;
               }
-           md = NULL;
 
             err = validate_cert_chain (ctrl, crlissuer_cert, NULL,
-                                       VALIDATE_MODE_CRL_RECURSIVE,
+                                       (VALIDATE_FLAG_TRUST_CONFIG
+                                        | VALIDATE_FLAG_CRL
+                                        | VALIDATE_FLAG_RECURSIVE),
                                        r_trust_anchor);
             if (err)
               {
@@ -1865,8 +1881,7 @@ crl_parse_insert (ctrl_t ctrl, ksba_crl_t crl,
 
 
  failure:
-  if (md)
-    abort_sig_check (crl, md);
+  abort_sig_check (crl, md);
   ksba_cert_release (crlissuer_cert);
   return err;
 }
@@ -2016,8 +2031,8 @@ crl_cache_insert (ctrl_t ctrl, const char *url, ksba_reader_t reader)
       nodename = utsbuf.nodename;
 #endif
 
-    estream_asprintf (&tmpfname, "crl-tmp-%s-%u-%p.db.tmp",
-                      nodename, (unsigned int)getpid (), &tmpfname);
+    gpgrt_asprintf (&tmpfname, "crl-tmp-%s-%u-%p.db.tmp",
+                    nodename, (unsigned int)getpid (), &tmpfname);
     if (!tmpfname)
       {
         err = gpg_error_from_syserror ();
@@ -2029,21 +2044,21 @@ crl_cache_insert (ctrl_t ctrl, const char *url, ksba_reader_t reader)
     fname = make_filename (opt.homedir_cache, DBDIR_D, tmpfname, NULL);
     xfree (tmpfname);
     if (!gnupg_remove (fname))
-      log_info (_("removed stale temporary cache file `%s'\n"), fname);
+      log_info (_("removed stale temporary cache file '%s'\n"), fname);
     else if (errno != ENOENT)
       {
         err = gpg_error_from_syserror ();
-        log_error (_("problem removing stale temporary cache file `%s': %s\n"),
+        log_error (_("problem removing stale temporary cache file '%s': %s\n"),
                    fname, gpg_strerror (err));
         goto leave;
       }
   }
 
-  fd_cdb = open (fname, O_WRONLY | O_CREAT | O_TRUNC, 0644);
+  fd_cdb = open (fname, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
   if (fd_cdb == -1)
     {
       err = gpg_error_from_errno (errno);
-      log_error (_("error creating temporary cache file `%s': %s\n"),
+      log_error (_("error creating temporary cache file '%s': %s\n"),
                  fname, strerror (errno));
       goto leave;
     }
@@ -2063,14 +2078,14 @@ crl_cache_insert (ctrl_t ctrl, const char *url, ksba_reader_t reader)
   if (cdb_make_finish (&cdb))
     {
       err = gpg_error_from_errno (errno);
-      log_error (_("error finishing temporary cache file `%s': %s\n"),
+      log_error (_("error finishing temporary cache file '%s': %s\n"),
                  fname, strerror (errno));
       goto leave;
     }
   if (close (fd_cdb))
     {
       err = gpg_error_from_errno (errno);
-      log_error (_("error closing temporary cache file `%s': %s\n"),
+      log_error (_("error closing temporary cache file '%s': %s\n"),
                  fname, strerror (errno));
       goto leave;
     }
@@ -2086,7 +2101,7 @@ crl_cache_insert (ctrl_t ctrl, const char *url, ksba_reader_t reader)
         err = gpg_error (GPG_ERR_CHECKSUM);
         goto leave;
       }
-    checksum = hexify_data (md5buf, 16);
+    checksum = hexify_data (md5buf, 16, 0);
   }
 
 
@@ -2176,7 +2191,7 @@ crl_cache_insert (ctrl_t ctrl, const char *url, ksba_reader_t reader)
   /* Rename the temporary DB to the real name. */
   newfname = make_db_file_name (entry->issuer_hash);
   if (opt.verbose)
-    log_info (_("creating cache file `%s'\n"), newfname);
+    log_info (_("creating cache file '%s'\n"), newfname);
 
   /* Just in case close unused matching files.  Actually we need this
      only under Windows but saving file descriptors is never bad.  */
@@ -2208,7 +2223,7 @@ crl_cache_insert (ctrl_t ctrl, const char *url, ksba_reader_t reader)
   if (rename (fname, newfname))
     {
       err = gpg_error_from_syserror ();
-      log_error (_("problem renaming `%s' to `%s': %s\n"),
+      log_error (_("problem renaming '%s' to '%s': %s\n"),
                  fname, newfname, gpg_strerror (err));
       goto leave;
     }
@@ -2295,7 +2310,7 @@ list_one_crl_entry (crl_cache_t cache, crl_cache_entry_t e, estream_t fp)
     return gpg_error (GPG_ERR_GENERAL);
 
   if (!e->dbfile_checked)
-    es_fprintf (fp, _(" ERROR: This cached CRL may has been tampered with!\n"));
+    es_fprintf (fp, _(" ERROR: This cached CRL may have been tampered with!\n"));
 
   es_putc ('\n', fp);
 
@@ -2351,7 +2366,7 @@ list_one_crl_entry (crl_cache_t cache, crl_cache_entry_t e, estream_t fp)
       if (reason & KSBA_CRLREASON_AFFILIATION_CHANGED )
         es_fputs( "affiliation_changed ", fp ), any = 1;
       if (reason & KSBA_CRLREASON_SUPERSEDED )
-        es_fputs( "superseeded", fp ), any = 1;
+        es_fputs( "superseded", fp ), any = 1;
       if (reason & KSBA_CRLREASON_CESSATION_OF_OPERATION )
         es_fputs( "cessation_of_operation", fp ), any = 1;
       if (reason & KSBA_CRLREASON_CERTIFICATE_HOLD )
@@ -2398,11 +2413,11 @@ crl_cache_load (ctrl_t ctrl, const char *filename)
   estream_t fp;
   ksba_reader_t reader;
 
-  fp = es_fopen (filename, "r");
+  fp = es_fopen (filename, "rb");
   if (!fp)
     {
       err = gpg_error_from_errno (errno);
-      log_error (_("can't open `%s': %s\n"), filename, strerror (errno));
+      log_error (_("can't open '%s': %s\n"), filename, strerror (errno));
       return err;
     }
 
@@ -2482,7 +2497,7 @@ crl_cache_reload_crl (ctrl_t ctrl, ksba_cert_t cert)
           any_dist_point = 1;
 
           if (opt.verbose)
-            log_info ("fetching CRL from `%s'\n", distpoint_uri);
+            log_info ("fetching CRL from '%s'\n", distpoint_uri);
           err = crl_fetch (ctrl, distpoint_uri, &reader);
           if (err)
             {
@@ -2518,6 +2533,9 @@ crl_cache_reload_crl (ctrl_t ctrl, ksba_cert_t cert)
       issuername_uri =  ksba_name_get_uri (issuername, 0);
       ksba_name_release (issuername); issuername = NULL;
 
+      /* Close the reader.  */
+      crl_close_reader (reader);
+      reader = NULL;
     }
   if (gpg_err_code (err) == GPG_ERR_EOF)
     err = 0;
@@ -2528,11 +2546,8 @@ crl_cache_reload_crl (ctrl_t ctrl, ksba_cert_t cert)
       if (opt.verbose)
         log_info ("no distribution point - trying issuer name\n");
 
-      if (reader)
-        {
-          crl_close_reader (reader);
-          reader = NULL;
-        }
+      crl_close_reader (reader);
+      reader = NULL;
 
       issuer = ksba_cert_get_issuer (cert, 0);
       if (!issuer)
@@ -2564,8 +2579,7 @@ crl_cache_reload_crl (ctrl_t ctrl, ksba_cert_t cert)
     }
 
  leave:
-  if (reader)
-    crl_close_reader (reader);
+  crl_close_reader (reader);
   xfree (distpoint_uri);
   xfree (issuername_uri);
   ksba_name_release (distpoint);