aes-s390x.pl: fix stg offset caused by typo in perlasm
[oweals/openssl.git] / apps / ocsp.c
index 6de0117d06c8d3f0585e2573082a81464af3eac9..b85a4d82c1bd1407a86edb38c32a9513c4c99126 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2018 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2001-2019 The OpenSSL Project Authors. All Rights Reserved.
  *
  * Licensed under the OpenSSL license (the "License").  You may not use
  * this file except in compliance with the License.  You can obtain a copy
@@ -36,7 +36,22 @@ NON_EMPTY_TRANSLATION_UNIT
 # include <openssl/x509v3.h>
 # include <openssl/rand.h>
 
-# if defined(OPENSSL_SYS_UNIX) && !defined(OPENSSL_NO_SOCK)
+#ifndef HAVE_FORK
+# if defined(OPENSSL_SYS_VMS) || defined(OPENSSL_SYS_WINDOWS)
+#  define HAVE_FORK 0
+# else
+#  define HAVE_FORK 1
+# endif
+#endif
+
+#if HAVE_FORK
+# undef NO_FORK
+#else
+# define NO_FORK
+#endif
+
+# if !defined(NO_FORK) && !defined(OPENSSL_NO_SOCK) \
+     && !defined(OPENSSL_NO_POSIX_IO)
 #  define OCSP_DAEMON
 #  include <sys/types.h>
 #  include <sys/wait.h>
@@ -52,6 +67,20 @@ NON_EMPTY_TRANSLATION_UNIT
 #  define LOG_ERR       2
 # endif
 
+# if defined(OPENSSL_SYS_VXWORKS)
+/* not supported */
+int setpgid(pid_t pid, pid_t pgid)
+{
+    errno = ENOSYS;
+    return 0;
+}
+/* not supported */
+pid_t fork(void)
+{
+    errno = ENOSYS;
+    return (pid_t) -1;
+}
+# endif
 /* Maximum leeway in validity period: default 5 minutes */
 # define MAX_VALIDITY_PERIOD    (5 * 60)
 
@@ -85,7 +114,7 @@ static int acfd = (int) INVALID_SOCKET;
 static int index_changed(CA_DB *);
 static void spawn_loop(void);
 static int print_syslog(const char *str, size_t len, void *levPtr);
-static void sock_timeout(int signum);
+static void socket_timeout(int signum);
 # endif
 
 # ifndef OPENSSL_NO_SOCK
@@ -230,9 +259,7 @@ int ocsp_main(int argc, char **argv)
     int accept_count = -1, add_nonce = 1, noverify = 0, use_ssl = -1;
     int vpmtouched = 0, badsig = 0, i, ignore_err = 0, nmin = 0, ndays = -1;
     int req_text = 0, resp_text = 0, ret = 1;
-# ifndef OPENSSL_NO_SOCK
     int req_timeout = -1;
-# endif
     long nsec = MAX_VALIDITY_PERIOD, maxage = -1;
     unsigned long sign_flags = 0, verify_flags = 0, rflags = 0;
     OPTION_CHOICE o;
@@ -483,11 +510,11 @@ int ocsp_main(int argc, char **argv)
                 goto opthelp;
             trailing_md = 1;
             break;
-# ifdef OCSP_DAEMON
         case OPT_MULTI:
+# ifdef OCSP_DAEMON
             multi = atoi(opt_arg());
-            break;
 # endif
+            break;
         }
     }
     if (trailing_md) {
@@ -552,7 +579,7 @@ int ocsp_main(int argc, char **argv)
     }
 
     if (ridx_filename != NULL
-        && (rkey != NULL || rsigner != NULL || rca_cert != NULL)) {
+        && (rkey == NULL || rsigner == NULL || rca_cert == NULL)) {
         BIO_printf(bio_err,
                    "Responder mode requires certificate, key, and CA.\n");
         goto end;
@@ -560,7 +587,7 @@ int ocsp_main(int argc, char **argv)
 
     if (ridx_filename != NULL) {
         rdb = load_index(ridx_filename, NULL);
-        if (rdb == NULL || !index_index(rdb)) {
+        if (rdb == NULL || index_index(rdb) <= 0) {
             ret = 1;
             goto end;
         }
@@ -570,7 +597,7 @@ int ocsp_main(int argc, char **argv)
     if (multi && acbio != NULL)
         spawn_loop();
     if (acbio != NULL && req_timeout > 0)
-        signal(SIGALRM, sock_timeout);
+        signal(SIGALRM, socket_timeout);
 #endif
 
     if (acbio != NULL)
@@ -583,10 +610,11 @@ redo_accept:
         if (index_changed(rdb)) {
             CA_DB *newrdb = load_index(ridx_filename, NULL);
 
-            if (newrdb != NULL) {
+            if (newrdb != NULL && index_index(newrdb) > 0) {
                 free_index(rdb);
                 rdb = newrdb;
             } else {
+                free_index(newrdb);
                 log_message(LOG_ERR, "error reloading updated index: %s",
                             ridx_filename);
             }
@@ -613,8 +641,10 @@ redo_accept:
         goto end;
     }
 
-    if (req != NULL && add_nonce)
-        OCSP_request_add1_nonce(req, NULL, -1);
+    if (req != NULL && add_nonce) {
+        if (!OCSP_request_add1_nonce(req, NULL, -1))
+            goto end;
+    }
 
     if (signfile != NULL) {
         if (keyfile == NULL)
@@ -697,10 +727,8 @@ redo_accept:
     if (i != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
         BIO_printf(out, "Responder Error: %s (%d)\n",
                    OCSP_response_status_str(i), i);
-        if (!ignore_err) {
-                ret = 0;
+        if (!ignore_err)
                 goto end;
-        }
     }
 
     if (resp_text)
@@ -814,7 +842,10 @@ log_message(int level, const char *fmt, ...)
     va_start(ap, fmt);
 # ifdef OCSP_DAEMON
     if (multi) {
-        vsyslog(level, fmt, ap);
+        char buf[1024];
+        if (vsnprintf(buf, sizeof(buf), fmt, ap) > 0) {
+            syslog(level, "%s", buf);
+        }
         if (level >= LOG_ERR)
             ERR_print_errors_cb(print_syslog, &level);
     }
@@ -862,6 +893,7 @@ static void killall(int ret, pid_t *kidpids)
     for (i = 0; i < multi; ++i)
         if (kidpids[i] != 0)
             (void)kill(kidpids[i], SIGTERM);
+    OPENSSL_free(kidpids);
     sleep(1);
     exit(ret);
 }
@@ -880,7 +912,6 @@ static void noteterm (int sig)
  */
 static void spawn_loop(void)
 {
-    const char *signame;
     pid_t *kidpids = NULL;
     int status;
     int procs = 0;
@@ -929,7 +960,10 @@ static void spawn_loop(void)
                     else if (WIFSIGNALED(status))
                         syslog(LOG_WARNING, "child process: %ld, term signal %d%s",
                                (long)fpid, WTERMSIG(status),
-                               WCOREDUMP(status) ? " (core dumped)" : "");
+#ifdef WCOREDUMP
+                               WCOREDUMP(status) ? " (core dumped)" :
+#endif
+                               "");
                     sleep(1);
                 }
                 break;
@@ -947,6 +981,7 @@ static void spawn_loop(void)
             sleep(30);
             break;
         case 0:             /* child */
+            OPENSSL_free(kidpids);
             signal(SIGINT, SIG_DFL);
             signal(SIGTERM, SIG_DFL);
             if (termsig)
@@ -973,9 +1008,7 @@ static void spawn_loop(void)
     }
 
     /* The loop above can only break on termsig */
-    signame = strsignal(termsig);
-    syslog(LOG_INFO, "terminating on signal: %s(%d)",
-           signame ? signame : "", termsig);
+    syslog(LOG_INFO, "terminating on signal: %d", termsig);
     killall(0, kidpids);
 }
 # endif
@@ -1214,7 +1247,10 @@ static void make_ocsp_response(BIO *err, OCSP_RESPONSE **resp, OCSP_REQUEST *req
             goto end;
         }
     }
-    OCSP_basic_sign_ctx(bs, rcert, mctx, rother, flags);
+    if (!OCSP_basic_sign_ctx(bs, rcert, mctx, rother, flags)) {
+        *resp = OCSP_response_create(OCSP_RESPONSE_STATUS_INTERNALERROR, bs);
+        goto end;
+    }
 
     if (badsig) {
         const ASN1_OCTET_STRING *sig = OCSP_resp_get0_signature(bs);
@@ -1316,7 +1352,7 @@ static int urldecode(char *p)
 # endif
 
 # ifdef OCSP_DAEMON
-static void sock_timeout(int signum)
+static void socket_timeout(int signum)
 {
     if (acfd != (int)INVALID_SOCKET)
         (void)shutdown(acfd, SHUT_RD);
@@ -1380,9 +1416,11 @@ static int do_responder(OCSP_REQUEST **preq, BIO **pcbio, BIO *acbio,
         *q = '\0';
 
         /*
-         * Skip "GET / HTTP..." requests often used by load-balancers
+         * Skip "GET / HTTP..." requests often used by load-balancers.  Note:
+         * 'p' was incremented above to point to the first byte *after* the
+         * leading slash, so with 'GET / ' it is now an empty string.
          */
-        if (p[1] == '\0')
+        if (p[0] == '\0')
             goto out;
 
         len = urldecode(p);