gpg: Remove PGP6 compliance mode.
[gnupg.git] / dirmngr / crlcache.c
index d10e3ca..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 "cdb.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";
 
 
@@ -479,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)
         {
@@ -857,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. */
@@ -992,7 +997,7 @@ 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;
@@ -1137,7 +1142,7 @@ 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"),
@@ -1210,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)
@@ -1343,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"),
@@ -1364,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);
@@ -1510,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;
@@ -1558,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)
@@ -1642,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);
 }
 
 
@@ -1700,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);
@@ -1837,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)
               {
@@ -1870,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;
 }
@@ -2044,7 +2054,7 @@ crl_cache_insert (ctrl_t ctrl, const char *url, ksba_reader_t reader)
       }
   }
 
-  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);
@@ -2091,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);
   }
 
 
@@ -2356,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 )
@@ -2403,7 +2413,7 @@ 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);
@@ -2523,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;
@@ -2533,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)
@@ -2569,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);