From c7d5ea2670c2f2ce855b099a14ca2c218661ad3f Mon Sep 17 00:00:00 2001 From: Viktor Dukhovni Date: Mon, 5 Mar 2018 14:40:02 -0500 Subject: [PATCH] Prepare to detect index changes in OCSP responder. 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 --- apps/apps.c | 21 +++++++++++++++++++++ apps/apps.h | 12 ++++++++++++ apps/ocsp.c | 30 +++++++++++++++--------------- crypto/err/err.c | 1 + include/openssl/err.h | 1 + 5 files changed, 50 insertions(+), 15 deletions(-) diff --git a/apps/apps.c b/apps/apps.c index ef573552eb..5a32dc0a02 100644 --- a/apps/apps.c +++ b/apps/apps.c @@ -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); } } diff --git a/apps/apps.h b/apps/apps.h index 3086f09f8c..5333c24767 100644 --- a/apps/apps.h +++ b/apps/apps.h @@ -14,6 +14,14 @@ # include "internal/nelem.h" # include +# ifndef NO_SYS_TYPES_H +# include +# endif +# ifndef OPENSSL_NO_POSIX_IO +# include +# include +# endif + # include # include # include @@ -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); diff --git a/apps/ocsp.c b/apps/ocsp.c index bd16a5b869..0f2690030d 100644 --- a/apps/ocsp.c +++ b/apps/ocsp.c @@ -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); diff --git a/crypto/err/err.c b/crypto/err/err.c index d69fbf870a..68afa93ae8 100644 --- a/crypto/err/err.c +++ b/crypto/err/err.c @@ -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}, }; diff --git a/include/openssl/err.h b/include/openssl/err.h index a602660c14..6d460be30c 100644 --- a/include/openssl/err.h +++ b/include/openssl/err.h @@ -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 */ -- 2.34.1