Prepare to detect index changes in OCSP responder.
authorViktor Dukhovni <openssl-users@dukhovni.org>
Mon, 5 Mar 2018 19:40:02 +0000 (14:40 -0500)
committerViktor Dukhovni <openssl-users@dukhovni.org>
Wed, 7 Mar 2018 16:03:01 +0000 (11:03 -0500)
Retain open file handle and previous stat data for the CA index
file, enabling detection and index reload (upcoming commit).

Check requirements before entering accept loop.

Reviewed-by: Matt Caswell <matt@openssl.org>
apps/apps.c
apps/apps.h
apps/ocsp.c
crypto/err/err.c
include/openssl/err.h

index ef57355..5a32dc0 100644 (file)
@@ -1538,12 +1538,27 @@ CA_DB *load_index(const char *dbfile, DB_ATTR *db_attr)
     BIO *in;
     CONF *dbattr_conf = NULL;
     char buf[BSIZE];
+#ifndef OPENSSL_NO_POSIX_IO
+    FILE *dbfp;
+    struct stat dbst;
+#endif
 
     in = BIO_new_file(dbfile, "r");
     if (in == NULL) {
         ERR_print_errors(bio_err);
         goto err;
     }
+
+#ifndef OPENSSL_NO_POSIX_IO
+    BIO_get_fp(in, &dbfp);
+    if (fstat(fileno(dbfp), &dbst) == -1) {
+        SYSerr(SYS_F_FSTAT, errno);
+        ERR_add_error_data(3, "fstat('", dbfile, "')");
+        ERR_print_errors(bio_err);
+        goto err;
+    }
+#endif
+
     if ((tmpdb = TXT_DB_read(in, DB_NUMBER)) == NULL)
         goto err;
 
@@ -1570,6 +1585,11 @@ CA_DB *load_index(const char *dbfile, DB_ATTR *db_attr)
         }
     }
 
+    retdb->dbfname = OPENSSL_strdup(dbfile);
+#ifndef OPENSSL_NO_POSIX_IO
+    retdb->dbst = dbst;
+#endif
+
  err:
     NCONF_free(dbattr_conf);
     TXT_DB_free(tmpdb);
@@ -1715,6 +1735,7 @@ void free_index(CA_DB *db)
 {
     if (db) {
         TXT_DB_free(db->db);
+        OPENSSL_free(db->dbfname);
         OPENSSL_free(db);
     }
 }
index 3086f09..5333c24 100644 (file)
 # include "internal/nelem.h"
 # include <assert.h>
 
+# ifndef NO_SYS_TYPES_H
+#  include <sys/types.h>
+# endif
+# ifndef OPENSSL_NO_POSIX_IO
+#  include <sys/stat.h>
+#  include <fcntl.h>
+# endif
+
 # include <openssl/e_os2.h>
 # include <openssl/ossl_typ.h>
 # include <openssl/bio.h>
@@ -509,6 +517,10 @@ typedef struct db_attr_st {
 typedef struct ca_db_st {
     DB_ATTR attributes;
     TXT_DB *db;
+    char *dbfname;
+# ifndef OPENSSL_NO_POSIX_IO
+    struct stat dbst;
+# endif
 } CA_DB;
 
 void* app_malloc(int sz, const char *what);
index bd16a5b..0f26900 100644 (file)
@@ -514,6 +514,21 @@ int ocsp_main(int argc, char **argv)
         if (rkey == NULL)
             goto end;
     }
+
+    if (ridx_filename && (!rkey || !rsigner || !rca_cert)) {
+        BIO_printf(bio_err,
+                   "Responder mode requires certificate, key, and CA.\n");
+        goto end;
+    }
+
+    if (ridx_filename) {
+        rdb = load_index(ridx_filename, NULL);
+        if (!rdb || !index_index(rdb)) {
+            ret = 1;
+            goto end;
+        }
+    }
+
     if (acbio != NULL)
         BIO_printf(bio_err, "Waiting for OCSP client connections...\n");
 
@@ -577,21 +592,6 @@ redo_accept:
         BIO_free(derbio);
     }
 
-    if (ridx_filename != NULL
-        && (rkey == NULL || rsigner == NULL || rca_cert == NULL)) {
-        BIO_printf(bio_err,
-                   "Need a responder certificate, key and CA for this operation!\n");
-        goto end;
-    }
-
-    if (ridx_filename != NULL && rdb == NULL) {
-        rdb = load_index(ridx_filename, NULL);
-        if (rdb == NULL)
-            goto end;
-        if (!index_index(rdb))
-            goto end;
-    }
-
     if (rdb != NULL) {
         make_ocsp_response(bio_err, &resp, req, rdb, rca_cert, rsigner, rkey,
                                rsign_md, rsign_sigopts, rother, rflags, nmin, ndays, badsig);
index d69fbf8..68afa93 100644 (file)
@@ -89,6 +89,7 @@ static ERR_STRING_DATA ERR_str_functs[] = {
     {ERR_PACK(0, SYS_F_IOCTL, 0), "ioctl"},
     {ERR_PACK(0, SYS_F_STAT, 0), "stat"},
     {ERR_PACK(0, SYS_F_FCNTL, 0), "fcntl"},
+    {ERR_PACK(0, SYS_F_FSTAT, 0), "fstat"},
     {0, NULL},
 };
 
index a602660..6d460be 100644 (file)
@@ -166,6 +166,7 @@ typedef struct err_state_st {
 # define SYS_F_IOCTL             21
 # define SYS_F_STAT              22
 # define SYS_F_FCNTL             23
+# define SYS_F_FSTAT             24
 
 /* reasons */
 # define ERR_R_SYS_LIB   ERR_LIB_SYS/* 2 */