summaryrefslogtreecommitdiff
path: root/modules/ssl
diff options
context:
space:
mode:
authorArno Töll <debian@toell.net>2012-01-08 22:53:17 +0100
committerArno Töll <debian@toell.net>2012-01-08 22:53:17 +0100
commite072a2dd866b7cb9f14319b80326a4e7fd16fcdf (patch)
treea49dfc56d94a26011fe157835ff6cbe14edbd8a9 /modules/ssl
parent0890390c00801651d08d3794e13b31a5dabbf5ef (diff)
downloadapache2-e072a2dd866b7cb9f14319b80326a4e7fd16fcdf.tar.gz
Imported Upstream version 2.3.16-beta
Diffstat (limited to 'modules/ssl')
-rw-r--r--modules/ssl/Makefile.in19
-rw-r--r--modules/ssl/NWGNUmakefile118
-rw-r--r--modules/ssl/README1
-rw-r--r--modules/ssl/config.m4129
-rw-r--r--modules/ssl/mod_ssl.c223
-rw-r--r--modules/ssl/mod_ssl.dep1017
-rw-r--r--modules/ssl/mod_ssl.dsp135
-rw-r--r--modules/ssl/mod_ssl.h23
-rw-r--r--modules/ssl/mod_ssl.mak733
-rw-r--r--modules/ssl/ssl_engine_config.c668
-rw-r--r--modules/ssl/ssl_engine_dh.c58
-rw-r--r--modules/ssl/ssl_engine_init.c603
-rw-r--r--modules/ssl/ssl_engine_io.c654
-rw-r--r--modules/ssl/ssl_engine_kernel.c943
-rw-r--r--modules/ssl/ssl_engine_log.c152
-rw-r--r--modules/ssl/ssl_engine_mutex.c61
-rw-r--r--modules/ssl/ssl_engine_ocsp.c297
-rw-r--r--modules/ssl/ssl_engine_pphrase.c189
-rw-r--r--modules/ssl/ssl_engine_rand.c10
-rw-r--r--modules/ssl/ssl_engine_vars.c317
-rw-r--r--modules/ssl/ssl_expr.c82
-rw-r--r--modules/ssl/ssl_expr.h113
-rw-r--r--modules/ssl/ssl_expr_eval.c345
-rw-r--r--modules/ssl/ssl_expr_parse.c618
-rw-r--r--modules/ssl/ssl_expr_parse.h30
-rw-r--r--modules/ssl/ssl_expr_parse.y154
-rw-r--r--modules/ssl/ssl_expr_scan.c1975
-rw-r--r--modules/ssl/ssl_expr_scan.l226
-rw-r--r--modules/ssl/ssl_private.h500
-rw-r--r--modules/ssl/ssl_scache.c197
-rw-r--r--modules/ssl/ssl_scache_dbm.c464
-rw-r--r--modules/ssl/ssl_scache_dc.c177
-rw-r--r--modules/ssl/ssl_scache_shmcb.c769
-rw-r--r--modules/ssl/ssl_toolkit_compat.h281
-rw-r--r--modules/ssl/ssl_util.c147
-rw-r--r--modules/ssl/ssl_util_ocsp.c308
-rw-r--r--modules/ssl/ssl_util_ssl.c282
-rw-r--r--modules/ssl/ssl_util_ssl.h39
-rw-r--r--modules/ssl/ssl_util_stapling.c688
39 files changed, 4568 insertions, 9177 deletions
diff --git a/modules/ssl/Makefile.in b/modules/ssl/Makefile.in
index 978b1c47..4395bc3a 100644
--- a/modules/ssl/Makefile.in
+++ b/modules/ssl/Makefile.in
@@ -18,22 +18,3 @@
#
include $(top_srcdir)/build/special.mk
-
-#
-# developer stuff
-# (we really don't expect end users to use these targets!)
-#
-
-ssl_expr_scan.c: $(top_srcdir)/modules/ssl/ssl_expr_scan.l ssl_expr_parse.h
- flex -Pssl_expr_yy -s -B $(top_srcdir)/modules/ssl/ssl_expr_scan.l
- sed -e '/$$Header:/d' -e "s|\"`pwd`/|\"|g" <lex.ssl_expr_yy.c >ssl_expr_scan.c && rm -f lex.ssl_expr_yy.c
-
-ssl_expr_parse.c ssl_expr_parse.h: $(top_srcdir)/modules/ssl/ssl_expr_parse.y
- yacc -d $(top_srcdir)/modules/ssl/ssl_expr_parse.y
- sed -e 's;yy;ssl_expr_yy;g' \
- -e "s|\"`pwd`/|\"|g" \
- -e '/#if defined(c_plusplus) || defined(__cplusplus)/,/#endif/d' \
- <y.tab.c >ssl_expr_parse.c && rm -f y.tab.c
- sed -e 's;yy;ssl_expr_yy;g' \
- <y.tab.h >ssl_expr_parse.h && rm -f y.tab.h
-
diff --git a/modules/ssl/NWGNUmakefile b/modules/ssl/NWGNUmakefile
index 048c1e42..933180f1 100644
--- a/modules/ssl/NWGNUmakefile
+++ b/modules/ssl/NWGNUmakefile
@@ -1,6 +1,9 @@
#
-# This Makefile requires the environment var OSSLSDK
+# This Makefile requires the environment var OSSLSDK
# pointing to the base directory of your OpenSSL SDK.
+# If you want to use the Novell NTLS SDK instead then
+# define NTLSSDK pointing to the base directory of the
+# SDK, and also set USE_NTLS=1
#
#
@@ -8,7 +11,7 @@
#
SUBDIRS = \
- $(EOLIST)
+ $(EOLIST)
#
# Get the 'head' of the build environment. This includes default targets and
@@ -23,23 +26,37 @@ include $(AP_WORK)/build/NWGNUhead.inc
# Make sure all needed macro's are defined
#
-OSSLINC = $(OSSLSDK)/outinc_nw_libc
-OSSLLIB = $(OSSLSDK)/out_nw_libc
-OSSLAPP = $(OSSLSDK)/apps
+ifeq "$(USE_NTLS)" "1"
+SSL_INC = $(NTLSSDK)/inc
+SSL_LIB = $(NTLSSDK)/imp
+SSL_BIN = $(NTLSSDK)/bin
+SSL_APP = $(NTLSSDK)/apps
+ifneq "$(wildcard $(SSL_INC)/openssl/opensslv.h)" "$(SSL_INC)/openssl/opensslv.h"
+$(error '$(NTLSSDK)' does NOT point to a valid NTLS SDK!)
+endif
+else
+SSL_INC = $(OSSLSDK)/outinc_nw_libc
+SSL_LIB = $(OSSLSDK)/out_nw_libc
+SSL_BIN = $(OSSLSDK)/out_nw_libc
+SSL_APP = $(OSSLSDK)/apps
+ifneq "$(wildcard $(SSL_INC)/openssl/opensslv.h)" "$(SSL_INC)/openssl/opensslv.h"
+$(error '$(OSSLSDK)' does NOT point to a valid OpenSSL SDK!)
+endif
+endif
#
# These directories will be at the beginning of the include list, followed by
# INCDIRS
#
XINCDIRS += \
+ $(SSL_INC) \
$(APR)/include \
$(APRUTIL)/include \
$(AP_WORK)/include \
+ $(AP_WORK)/modules/cache \
+ $(AP_WORK)/modules/generators \
+ $(AP_WORK)/server/mpm/NetWare \
$(NWOS) \
- $(STDMOD)/generators \
- $(SERVER)/mpm/NetWare \
- $(OSSLINC) \
- $(OSSLINC)/openssl \
$(EOLIST)
#
@@ -59,7 +76,7 @@ XDEFINES += \
# These flags will be added to the link.opt file
#
XLFLAGS += \
- -l $(OSSLLIB) \
+ -l $(SSL_LIB) \
$(EOLIST)
#
@@ -116,10 +133,14 @@ endif
NLM_NAME = mod_ssl
#
-# This is used by the link '-desc ' directive.
+# This is used by the link '-desc ' directive.
# If left blank, NLM_NAME will be used.
#
-NLM_DESCRIPTION = Apache $(VERSION_STR) SSL module
+ifeq "$(USE_NTLS)" "1"
+NLM_DESCRIPTION = Apache $(VERSION_STR) SSL module (NTLS)
+else
+NLM_DESCRIPTION = Apache $(VERSION_STR) SSL module (OpenSSL)
+endif
#
# This is used by the '-threadname' directive. If left blank,
@@ -128,16 +149,16 @@ NLM_DESCRIPTION = Apache $(VERSION_STR) SSL module
NLM_THREAD_NAME = $(NLM_NAME)
#
-# If this is specified, it will override VERSION value in
+# If this is specified, it will override VERSION value in
# $(AP_WORK)/build/NWGNUenvironment.inc
#
-NLM_VERSION =
+NLM_VERSION =
#
# If this is specified, it will override the default of 64K
#
NLM_STACK_SIZE = 8192
-
+
#
# If this is specified it will be used by the link '-entry' directive
@@ -158,13 +179,13 @@ NLM_CHECK_SYM =
# If this is specified it will be used by the link '-flags' directive
#
NLM_FLAGS =
-
+
#
-# If this is specified it will be linked in with the XDCData option in the def
+# If this is specified it will be linked in with the XDCData option in the def
# file instead of the default of $(NWOS)/apache.xdc. XDCData can be disabled
# by setting APACHE_UNIPROC in the environment
#
-XDCDATA =
+XDCDATA =
#
# Declare all target files (you must add your files here)
@@ -196,10 +217,15 @@ FILES_nlm_objs := $(patsubst %.c,$(OBJDIR)/%.o,$(wildcard *.c))
#
FILES_nlm_libs = \
$(PRELUDE) \
- $(OSSLLIB)/crypto.lib \
- $(OSSLLIB)/ssl.lib \
$(EOLIST)
+ifneq "$(USE_NTLS)" "1"
+FILES_nlm_libs += \
+ $(SSL_LIB)/crypto.lib \
+ $(SSL_LIB)/ssl.lib \
+ $(EOLIST)
+endif
+
#
# These are the modules that the above NLM target depends on to load.
# These will be added as a module command in the link.opt file.
@@ -209,11 +235,16 @@ FILES_nlm_modules = \
Libc \
$(EOLIST)
+ifeq "$(USE_NTLS)" "1"
+FILES_nlm_modules += ntls \
+ $(EOLIST)
+endif
+
#
# If the nlm has a msg file, put it's path here
#
FILE_nlm_msg =
-
+
#
# If the nlm has a hlp file put it's path here
#
@@ -231,25 +262,33 @@ FILES_nlm_Ximports = \
@libc.imp \
@aprlib.imp \
@httpd.imp \
+ $(EOLIST)
+
+# Don't link with Winsock if standard sockets are being used
+ifneq "$(USE_STDSOCKETS)" "1"
+FILES_nlm_Ximports += @ws2nlm.imp \
+ $(EOLIST)
+endif
+
+ifeq "$(USE_NTLS)" "1"
+FILES_nlm_Ximports += @ntls.imp \
+ $(EOLIST)
+else
+FILES_nlm_Ximports += \
GetProcessSwitchCount \
RunningProcess \
GetSuperHighResolutionTimer \
$(EOLIST)
-
-# Don't link with Winsock if standard sockets are being used
-ifndef USE_STDSOCKETS
-FILES_nlm_Ximports += @ws2nlm.imp \
- $(EOLIST)
endif
-
-#
+
+#
# Any symbols exported to here
#
FILES_nlm_exports = \
ssl_module \
$(EOLIST)
-#
+#
# These are the OBJ files needed to create the LIB target above.
# Paths must all use the '/' character
#
@@ -265,32 +304,19 @@ libs :: $(OBJDIR) $(TARGET_lib)
nlms :: libs $(TARGET_nlm)
#
-# Updated this target to create necessary directories and copy files to the
+# Updated this target to create necessary directories and copy files to the
# correct place. (See $(AP_WORK)/build/NWGNUhead.inc for examples)
#
install :: nlms FORCE
- $(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
- $(call COPY,$(OSSLLIB)/openssl.nlm ,$(INSTALLBASE)/bin/)
- $(call COPY,$(OSSLAPP)/openssl.cnf ,$(INSTALLBASE)/bin/)
+ $(call COPY,$(OBJDIR)/*.nlm, $(INSTALLBASE)/modules/)
+ $(call COPY,$(SSL_BIN)/openssl.nlm, $(INSTALLBASE)/bin/)
+ $(call COPY,$(SSL_APP)/openssl.cnf, $(INSTALLBASE)/bin/)
#
# Any specialized rules here
#
vpath %.c $(AP_WORK)/modules/arch/netware
-# Make sure that the build doesn't attempt to regenerate the shipping files.
-# On Windows we use 'copy /b file.ext +,,' to assign the current time and date
-# to a file without modifying the file (the TOUCH macro uses this) - see also:
-# http://technet.microsoft.com/en-us/library/bb490886.aspx
-ssl_expr_parse.h : ssl_expr_parse.y
- $(call TOUCH, $@)
-
-ssl_expr_parse.c : ssl_expr_parse.y
- $(call TOUCH, $@)
-
-ssl_expr_scan.c : ssl_expr_scan.l
- $(call TOUCH, $@)
-
#
# Include the 'tail' makefile that has targets that depend on variables defined
# in this makefile
diff --git a/modules/ssl/README b/modules/ssl/README
index 49ef6623..c46377f2 100644
--- a/modules/ssl/README
+++ b/modules/ssl/README
@@ -98,7 +98,6 @@ MAJOR CHANGES
the original SSLProxy* directives
o per-directory SSLCACertificate{File,Path} is now thread-safe but
requires SSL_set_cert_store patch to OpenSSL
- o RSA sslc is supported via ssl_toolkit_compat.h
o the ssl_engine_{ds,ext}.c source files are obsolete and no longer
exist
diff --git a/modules/ssl/config.m4 b/modules/ssl/config.m4
index 06479a9e..1ee122e2 100644
--- a/modules/ssl/config.m4
+++ b/modules/ssl/config.m4
@@ -1,89 +1,17 @@
-dnl Copyright 2001-2005 The Apache Software Foundation or its licensors, as
-dnl applicable.
-dnl Licensed under the Apache License, Version 2.0 (the "License");
-dnl you may not use this file except in compliance with the License.
-dnl You may obtain a copy of the License at
-dnl
-dnl http://www.apache.org/licenses/LICENSE-2.0
-dnl
-dnl Unless required by applicable law or agreed to in writing, software
-dnl distributed under the License is distributed on an "AS IS" BASIS,
-dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-dnl See the License for the specific language governing permissions and
-dnl limitations under the License.
-
-AC_DEFUN([CHECK_DISTCACHE], [
- AC_MSG_CHECKING(whether Distcache is required)
- ap_ssltk_dc="no"
- tmp_nomessage=""
- tmp_forced="no"
- AC_ARG_ENABLE(distcache,
- APACHE_HELP_STRING(--enable-distcache,Select distcache support in mod_ssl),
- ap_ssltk_dc="$enableval"
- tmp_nomessage=""
- tmp_forced="yes"
- if test "x$ap_ssltk_dc" = "x"; then
- ap_ssltk_dc="yes"
- dnl our "error"s become "tests revealed that..."
- tmp_forced="no"
- fi
- if test "$ap_ssltk_dc" != "yes" -a "$ap_ssltk_dc" != "no"; then
- tmp_nomessage="--enable-distcache had illegal syntax - disabling"
- ap_ssltk_dc="no"
- fi)
- if test "$tmp_forced" = "no"; then
- AC_MSG_RESULT($ap_ssltk_dc (default))
- else
- AC_MSG_RESULT($ap_ssltk_dc (specified))
- fi
- if test "$tmp_forced" = "yes" -a "x$ap_ssltk_dc" = "xno" -a "x$tmp_nomessage" != "x"; then
- AC_MSG_ERROR(distcache support failed: $tmp_nomessage)
- fi
- if test "$ap_ssltk_dc" = "yes"; then
- AC_CHECK_HEADER(
- [distcache/dc_client.h],
- [],
- [tmp_nomessage="can't include distcache headers"
- ap_ssltk_dc="no"])
- if test "$tmp_forced" = "yes" -a "x$ap_ssltk_dc" = "xno"; then
- AC_MSG_ERROR(distcache support failed: $tmp_nomessage)
- fi
- fi
- if test "$ap_ssltk_dc" = "yes"; then
- AC_MSG_CHECKING(for Distcache version)
- AC_TRY_COMPILE(
-[#include <distcache/dc_client.h>],
-[#if DISTCACHE_CLIENT_API != 0x0001
-#error "distcache API version is unrecognised"
-#endif],
-[],
-[tmp_nomessage="distcache has an unsupported API version"
-ap_ssltk_dc="no"])
- AC_MSG_RESULT($ap_ssltk_dc)
- if test "$tmp_forced" = "yes" -a "x$ap_ssltk_dc" = "xno"; then
- AC_MSG_ERROR(distcache support failed: $tmp_nomessage)
- fi
- fi
- if test "$ap_ssltk_dc" = "yes"; then
- AC_MSG_CHECKING(for Distcache libraries)
- save_libs=$LIBS
- LIBS="$LIBS -ldistcache -lnal"
- AC_TRY_LINK(
- [#include <distcache/dc_client.h>],
- [DC_CTX *foo = DC_CTX_new((const char *)0,0);],
- [],
- [tmp_no_message="failed to link with distcache libraries"
- ap_ssltk_dc="no"])
- LIBS=$save_libs
- AC_MSG_RESULT($ap_ssltk_dc)
- if test "$tmp_forced" = "yes" -a "x$ap_ssltk_dc" = "xno"; then
- AC_MSG_ERROR(distcache support failed: $tmp_nomessage)
- else
- APR_ADDTO(MOD_SSL_LDADD, [-ldistcache -lnal])
- AC_DEFINE(HAVE_DISTCACHE, 1, [Define if distcache support is enabled])
- fi
- fi
-])
+dnl Licensed to the Apache Software Foundation (ASF) under one or more
+dnl contributor license agreements. See the NOTICE file distributed with
+dnl this work for additional information regarding copyright ownership.
+dnl The ASF licenses this file to You under the Apache License, Version 2.0
+dnl (the "License"); you may not use this file except in compliance with
+dnl the License. You may obtain a copy of the License at
+dnl
+dnl http://www.apache.org/licenses/LICENSE-2.0
+dnl
+dnl Unless required by applicable law or agreed to in writing, software
+dnl distributed under the License is distributed on an "AS IS" BASIS,
+dnl WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+dnl See the License for the specific language governing permissions and
+dnl limitations under the License.
dnl # start of module specific part
APACHE_MODPATH_INIT(ssl)
@@ -101,26 +29,25 @@ ssl_engine_mutex.lo dnl
ssl_engine_pphrase.lo dnl
ssl_engine_rand.lo dnl
ssl_engine_vars.lo dnl
-ssl_expr.lo dnl
-ssl_expr_eval.lo dnl
-ssl_expr_parse.lo dnl
-ssl_expr_scan.lo dnl
ssl_scache.lo dnl
-ssl_scache_dbm.lo dnl
-ssl_scache_shmcb.lo dnl
-ssl_scache_dc.lo dnl
+ssl_util_stapling.lo dnl
ssl_util.lo dnl
ssl_util_ssl.lo dnl
+ssl_engine_ocsp.lo dnl
+ssl_util_ocsp.lo dnl
"
dnl # hook module into the Autoconf mechanism (--enable-ssl option)
-APACHE_MODULE(ssl, [SSL/TLS support (mod_ssl)], $ssl_objs, , no, [
- APACHE_CHECK_SSL_TOOLKIT
- APR_SETVAR(MOD_SSL_LDADD, [\$(SSL_LIBS)])
- CHECK_DISTCACHE
- if test "x$enable_ssl" = "xshared"; then
- # The only symbol which needs to be exported is the module
- # structure, so ask libtool to hide everything else:
- APR_ADDTO(MOD_SSL_LDADD, [-export-symbols-regex ssl_module])
+APACHE_MODULE(ssl, [SSL/TLS support (mod_ssl)], $ssl_objs, , most, [
+ APACHE_CHECK_OPENSSL
+ if test "$ac_cv_openssl" = "yes" ; then
+ APR_ADDTO(MOD_SSL_LDADD, [\$(SSL_LIBS)])
+ if test "x$enable_ssl" = "xshared"; then
+ # The only symbol which needs to be exported is the module
+ # structure, so ask libtool to hide everything else:
+ APR_ADDTO(MOD_SSL_LDADD, [-export-symbols-regex ssl_module])
+ fi
+ else
+ enable_ssl=no
fi
])
diff --git a/modules/ssl/mod_ssl.c b/modules/ssl/mod_ssl.c
index 5edb1c82..57bf2d94 100644
--- a/modules/ssl/mod_ssl.c
+++ b/modules/ssl/mod_ssl.c
@@ -27,6 +27,9 @@
#include "ssl_private.h"
#include "mod_ssl.h"
#include "util_md5.h"
+#include "util_mutex.h"
+#include "ap_provider.h"
+
#include <assert.h>
/*
@@ -47,103 +50,87 @@
#define AP_END_CMD { NULL }
-const char ssl_valid_ssl_mutex_string[] =
- "Valid SSLMutex mechanisms are: `none', `default'"
-#if APR_HAS_FLOCK_SERIALIZE
- ", `flock:/path/to/file'"
-#endif
-#if APR_HAS_FCNTL_SERIALIZE
- ", `fcntl:/path/to/file'"
-#endif
-#if APR_HAS_SYSVSEM_SERIALIZE && !defined(PERCHILD_MPM)
- ", `sysvsem'"
-#endif
-#if APR_HAS_POSIXSEM_SERIALIZE
- ", `posixsem'"
-#endif
-#if APR_HAS_PROC_PTHREAD_SERIALIZE
- ", `pthread'"
-#endif
-#if APR_HAS_FLOCK_SERIALIZE || APR_HAS_FCNTL_SERIALIZE
- ", `file:/path/to/file'"
-#endif
-#if (APR_HAS_SYSVSEM_SERIALIZE && !defined(PERCHILD_MPM)) || APR_HAS_POSIXSEM_SERIALIZE
- ", `sem'"
-#endif
- " ";
-
static const command_rec ssl_config_cmds[] = {
/*
* Global (main-server) context configuration directives
*/
- SSL_CMD_SRV(Mutex, TAKE1, ssl_valid_ssl_mutex_string)
SSL_CMD_SRV(PassPhraseDialog, TAKE1,
"SSL dialog mechanism for the pass phrase query "
- "(`builtin', `|/path/to/pipe_program`, "
- "or `exec:/path/to/cgi_program')")
+ "('builtin', '|/path/to/pipe_program', "
+ "or 'exec:/path/to/cgi_program')")
SSL_CMD_SRV(SessionCache, TAKE1,
"SSL Session Cache storage "
- "(`none', `nonenotnull', `dbm:/path/to/file')")
+ "('none', 'nonenotnull', 'dbm:/path/to/file')")
#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
SSL_CMD_SRV(CryptoDevice, TAKE1,
"SSL external Crypto Device usage "
- "(`builtin', `...')")
+ "('builtin', '...')")
#endif
SSL_CMD_SRV(RandomSeed, TAKE23,
"SSL Pseudo Random Number Generator (PRNG) seeding source "
- "(`startup|connect builtin|file:/path|exec:/path [bytes]')")
+ "('startup|connect builtin|file:/path|exec:/path [bytes]')")
/*
* Per-server context configuration directives
*/
SSL_CMD_SRV(Engine, TAKE1,
"SSL switch for the protocol engine "
- "(`on', `off')")
+ "('on', 'off')")
SSL_CMD_SRV(FIPS, FLAG,
"Enable FIPS-140 mode "
"(`on', `off')")
SSL_CMD_ALL(CipherSuite, TAKE1,
"Colon-delimited list of permitted SSL Ciphers "
- "(`XXX:...:XXX' - see manual)")
+ "('XXX:...:XXX' - see manual)")
SSL_CMD_SRV(CertificateFile, TAKE1,
"SSL Server Certificate file "
- "(`/path/to/file' - PEM or DER encoded)")
+ "('/path/to/file' - PEM or DER encoded)")
SSL_CMD_SRV(CertificateKeyFile, TAKE1,
"SSL Server Private Key file "
- "(`/path/to/file' - PEM or DER encoded)")
+ "('/path/to/file' - PEM or DER encoded)")
SSL_CMD_SRV(CertificateChainFile, TAKE1,
"SSL Server CA Certificate Chain file "
- "(`/path/to/file' - PEM encoded)")
+ "('/path/to/file' - PEM encoded)")
+ SSL_CMD_SRV(PKCS7CertificateFile, TAKE1,
+ "PKCS#7 file containing server certificate and chain"
+ " certificates ('/path/to/file' - PEM encoded)")
+#ifdef HAVE_TLS_SESSION_TICKETS
+ SSL_CMD_SRV(SessionTicketKeyFile, TAKE1,
+ "TLS session ticket encryption/decryption key file (RFC 5077) "
+ "('/path/to/file' - file with 48 bytes of random data)")
+#endif
SSL_CMD_ALL(CACertificatePath, TAKE1,
"SSL CA Certificate path "
- "(`/path/to/dir' - contains PEM encoded files)")
+ "('/path/to/dir' - contains PEM encoded files)")
SSL_CMD_ALL(CACertificateFile, TAKE1,
"SSL CA Certificate file "
- "(`/path/to/file' - PEM encoded)")
+ "('/path/to/file' - PEM encoded)")
SSL_CMD_SRV(CADNRequestPath, TAKE1,
"SSL CA Distinguished Name path "
- "(`/path/to/dir' - symlink hashes to PEM of acceptable CA names to request)")
+ "('/path/to/dir' - symlink hashes to PEM of acceptable CA names to request)")
SSL_CMD_SRV(CADNRequestFile, TAKE1,
"SSL CA Distinguished Name file "
- "(`/path/to/file' - PEM encoded to derive acceptable CA names to request)")
+ "('/path/to/file' - PEM encoded to derive acceptable CA names to request)")
SSL_CMD_SRV(CARevocationPath, TAKE1,
"SSL CA Certificate Revocation List (CRL) path "
- "(`/path/to/dir' - contains PEM encoded files)")
+ "('/path/to/dir' - contains PEM encoded files)")
SSL_CMD_SRV(CARevocationFile, TAKE1,
"SSL CA Certificate Revocation List (CRL) file "
- "(`/path/to/file' - PEM encoded)")
+ "('/path/to/file' - PEM encoded)")
+ SSL_CMD_SRV(CARevocationCheck, TAKE1,
+ "SSL CA Certificate Revocation List (CRL) checking mode")
SSL_CMD_ALL(VerifyClient, TAKE1,
"SSL Client verify type "
- "(`none', `optional', `require', `optional_no_ca')")
+ "('none', 'optional', 'require', 'optional_no_ca')")
SSL_CMD_ALL(VerifyDepth, TAKE1,
"SSL Client verify depth "
- "(`N' - number of intermediate certificates)")
+ "('N' - number of intermediate certificates)")
SSL_CMD_SRV(SessionCacheTimeout, TAKE1,
"SSL Session Cache object lifetime "
- "(`N' - number of seconds)")
+ "('N' - number of seconds)")
SSL_CMD_SRV(Protocol, RAW_ARGS,
"Enable or disable various SSL protocols"
- "(`[+-][SSLv2|SSLv3|TLSv1] ...' - see manual)")
+ "('[+-][SSLv2|SSLv3|TLSv1] ...' - see manual)")
SSL_CMD_SRV(HonorCipherOrder, FLAG,
"Use the server's cipher ordering preference")
SSL_CMD_SRV(InsecureRenegotiation, FLAG,
@@ -158,37 +145,43 @@ static const command_rec ssl_config_cmds[] = {
*/
SSL_CMD_SRV(ProxyEngine, FLAG,
"SSL switch for the proxy protocol engine "
- "(`on', `off')")
+ "('on', 'off')")
SSL_CMD_SRV(ProxyProtocol, RAW_ARGS,
"SSL Proxy: enable or disable SSL protocol flavors "
- "(`[+-][SSLv2|SSLv3|TLSv1] ...' - see manual)")
+ "('[+-][SSLv2|SSLv3|TLSv1] ...' - see manual)")
SSL_CMD_SRV(ProxyCipherSuite, TAKE1,
"SSL Proxy: colon-delimited list of permitted SSL ciphers "
- "(`XXX:...:XXX' - see manual)")
+ "('XXX:...:XXX' - see manual)")
SSL_CMD_SRV(ProxyVerify, TAKE1,
"SSL Proxy: whether to verify the remote certificate "
- "(`on' or `off')")
+ "('on' or 'off')")
SSL_CMD_SRV(ProxyVerifyDepth, TAKE1,
"SSL Proxy: maximum certificate verification depth "
- "(`N' - number of intermediate certificates)")
+ "('N' - number of intermediate certificates)")
SSL_CMD_SRV(ProxyCACertificateFile, TAKE1,
"SSL Proxy: file containing server certificates "
- "(`/path/to/file' - PEM encoded certificates)")
+ "('/path/to/file' - PEM encoded certificates)")
SSL_CMD_SRV(ProxyCACertificatePath, TAKE1,
"SSL Proxy: directory containing server certificates "
- "(`/path/to/dir' - contains PEM encoded certificates)")
+ "('/path/to/dir' - contains PEM encoded certificates)")
SSL_CMD_SRV(ProxyCARevocationPath, TAKE1,
"SSL Proxy: CA Certificate Revocation List (CRL) path "
- "(`/path/to/dir' - contains PEM encoded files)")
+ "('/path/to/dir' - contains PEM encoded files)")
SSL_CMD_SRV(ProxyCARevocationFile, TAKE1,
"SSL Proxy: CA Certificate Revocation List (CRL) file "
- "(`/path/to/file' - PEM encoded)")
+ "('/path/to/file' - PEM encoded)")
+ SSL_CMD_SRV(ProxyCARevocationCheck, TAKE1,
+ "SSL Proxy: CA Certificate Revocation List (CRL) checking mode")
SSL_CMD_SRV(ProxyMachineCertificateFile, TAKE1,
"SSL Proxy: file containing client certificates "
- "(`/path/to/file' - PEM encoded certificates)")
+ "('/path/to/file' - PEM encoded certificates)")
SSL_CMD_SRV(ProxyMachineCertificatePath, TAKE1,
"SSL Proxy: directory containing client certificates "
- "(`/path/to/dir' - contains PEM encoded certificates)")
+ "('/path/to/dir' - contains PEM encoded certificates)")
+ SSL_CMD_SRV(ProxyMachineCertificateChainFile, TAKE1,
+ "SSL Proxy: file containing issuing certificates "
+ "of the client certificate "
+ "(`/path/to/file' - PEM encoded certificates)")
SSL_CMD_SRV(ProxyCheckPeerExpire, FLAG,
"SSL Proxy: check the peers certificate expiration date")
SSL_CMD_SRV(ProxyCheckPeerCN, FLAG,
@@ -199,7 +192,7 @@ static const command_rec ssl_config_cmds[] = {
*/
SSL_CMD_DIR(Options, OPTIONS, RAW_ARGS,
"Set one or more options to configure the SSL engine"
- "(`[+-]option[=value] ...' - see manual)")
+ "('[+-]option[=value] ...' - see manual)")
SSL_CMD_DIR(RequireSSL, AUTHCFG, NO_ARGS,
"Require the SSL protocol for the per-directory context "
"(no arguments)")
@@ -211,6 +204,48 @@ static const command_rec ssl_config_cmds[] = {
"request body if a per-location SSL renegotiation is required due to "
"changed access control requirements")
+ SSL_CMD_SRV(OCSPEnable, FLAG,
+ "Enable use of OCSP to verify certificate revocation ('on', 'off')")
+ SSL_CMD_SRV(OCSPDefaultResponder, TAKE1,
+ "URL of the default OCSP Responder")
+ SSL_CMD_SRV(OCSPOverrideResponder, FLAG,
+ "Force use of the default responder URL ('on', 'off')")
+ SSL_CMD_SRV(OCSPResponseTimeSkew, TAKE1,
+ "Maximum time difference in OCSP responses")
+ SSL_CMD_SRV(OCSPResponseMaxAge, TAKE1,
+ "Maximum age of OCSP responses")
+ SSL_CMD_SRV(OCSPResponderTimeout, TAKE1,
+ "OCSP responder query timeout")
+
+#ifdef HAVE_OCSP_STAPLING
+ /*
+ * OCSP Stapling options
+ */
+ SSL_CMD_SRV(StaplingCache, TAKE1,
+ "SSL Stapling Response Cache storage "
+ "(`dbm:/path/to/file')")
+ SSL_CMD_SRV(UseStapling, FLAG,
+ "SSL switch for the OCSP Stapling protocol " "(`on', `off')")
+ SSL_CMD_SRV(StaplingResponseTimeSkew, TAKE1,
+ "SSL stapling option for maximum time difference in OCSP responses")
+ SSL_CMD_SRV(StaplingResponderTimeout, TAKE1,
+ "SSL stapling option for OCSP responder timeout")
+ SSL_CMD_SRV(StaplingResponseMaxAge, TAKE1,
+ "SSL stapling option for maximum age of OCSP responses")
+ SSL_CMD_SRV(StaplingStandardCacheTimeout, TAKE1,
+ "SSL stapling option for normal OCSP Response Cache Lifetime")
+ SSL_CMD_SRV(StaplingReturnResponderErrors, FLAG,
+ "SSL stapling switch to return Status Errors Back to Client"
+ "(`on', `off')")
+ SSL_CMD_SRV(StaplingFakeTryLater, FLAG,
+ "SSL stapling switch to send tryLater response to client on error "
+ "(`on', `off')")
+ SSL_CMD_SRV(StaplingErrorCacheTimeout, TAKE1,
+ "SSL stapling option for OCSP Response Error Cache Lifetime")
+ SSL_CMD_SRV(StaplingForceURL, TAKE1,
+ "SSL stapling option to Force the OCSP Stapling URL")
+#endif
+
/* Deprecated directives. */
AP_INIT_RAW_ARGS("SSLLog", ap_set_deprecated, NULL, OR_ALL,
"SSLLog directive is no longer supported - use ErrorLog."),
@@ -228,15 +263,11 @@ static apr_status_t ssl_cleanup_pre_config(void *data)
/*
* Try to kill the internals of the SSL library.
*/
-#ifdef HAVE_OPENSSL
-#if OPENSSL_VERSION_NUMBER >= 0x00907001
/* Corresponds to OPENSSL_load_builtin_modules():
* XXX: borrowed from apps.h, but why not CONF_modules_free()
* which also invokes CONF_modules_finish()?
*/
CONF_modules_unload(1);
-#endif
-#endif
/* Corresponds to SSL_library_init: */
EVP_cleanup();
#if HAVE_ENGINE_LOAD_BUILTIN_ENGINES
@@ -270,20 +301,14 @@ static int ssl_hook_pre_config(apr_pool_t *pconf,
* code can successfully test the SSL environment.
*/
CRYPTO_malloc_init();
-#ifdef HAVE_OPENSSL
ERR_load_crypto_strings();
-#endif
SSL_load_error_strings();
SSL_library_init();
#if HAVE_ENGINE_LOAD_BUILTIN_ENGINES
ENGINE_load_builtin_engines();
#endif
-#ifdef HAVE_OPENSSL
OpenSSL_add_all_algorithms();
-#if OPENSSL_VERSION_NUMBER >= 0x00907001
OPENSSL_load_builtin_modules();
-#endif
-#endif
/*
* Let us cleanup the ssl library when the module is unloaded
@@ -297,6 +322,12 @@ static int ssl_hook_pre_config(apr_pool_t *pconf,
/* Register to handle mod_status status page generation */
ssl_scache_status_register(pconf);
+ /* Register mutex type names so they can be configured with Mutex */
+ ap_mutex_register(pconf, SSL_CACHE_MUTEX_TYPE, NULL, APR_LOCK_DEFAULT, 0);
+#ifdef HAVE_OCSP_STAPLING
+ ap_mutex_register(pconf, SSL_STAPLING_MUTEX_TYPE, NULL, APR_LOCK_DEFAULT, 0);
+#endif
+
return OK;
}
@@ -311,6 +342,7 @@ static SSLConnRec *ssl_init_connection_ctx(conn_rec *c)
sslconn = apr_pcalloc(c->pool, sizeof(*sslconn));
sslconn->server = c->base_server;
+ sslconn->verify_depth = UNSET;
myConnConfigSet(c, sslconn);
@@ -325,7 +357,7 @@ int ssl_proxy_enable(conn_rec *c)
sc = mySrvConfig(sslconn->server);
if (!sc->proxy_enabled) {
- ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c,
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(01961)
"SSL Proxy requested for %s but not enabled "
"[Hint: SSLProxyEngine]", sc->vhost_id);
@@ -361,7 +393,7 @@ int ssl_engine_disable(conn_rec *c)
return 1;
}
-int ssl_init_ssl_connection(conn_rec *c)
+int ssl_init_ssl_connection(conn_rec *c, request_rec *r)
{
SSLSrvConfigRec *sc;
SSL *ssl;
@@ -389,10 +421,10 @@ int ssl_init_ssl_connection(conn_rec *c)
* so we can detach later.
*/
if (!(ssl = SSL_new(mctx->ssl_ctx))) {
- ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c,
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(01962)
"Unable to create a new SSL connection from the SSL "
"context");
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, server);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, server);
c->aborted = 1;
@@ -405,9 +437,9 @@ int ssl_init_ssl_connection(conn_rec *c)
if (!SSL_set_session_id_context(ssl, (unsigned char *)vhost_md5,
APR_MD5_DIGESTSIZE*2))
{
- ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c,
- "Unable to set session id context to `%s'", vhost_md5);
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, server);
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(01963)
+ "Unable to set session id context to '%s'", vhost_md5);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, server);
c->aborted = 1;
@@ -424,10 +456,13 @@ int ssl_init_ssl_connection(conn_rec *c)
*/
SSL_set_tmp_rsa_callback(ssl, ssl_callback_TmpRSA);
SSL_set_tmp_dh_callback(ssl, ssl_callback_TmpDH);
+#ifndef OPENSSL_NO_EC
+ SSL_set_tmp_ecdh_callback(ssl, ssl_callback_TmpECDH);
+#endif
SSL_set_verify_result(ssl, X509_V_OK);
- ssl_io_filter_init(c, ssl);
+ ssl_io_filter_init(c, r, ssl);
return APR_SUCCESS;
}
@@ -490,21 +525,11 @@ static int ssl_hook_pre_connection(conn_rec *c, void *csd)
* later access inside callback functions
*/
- ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c,
+ ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c, APLOGNO(01964)
"Connection to child %ld established "
"(server %s)", c->id, sc->vhost_id);
- return ssl_init_ssl_connection(c);
-}
-
-
-static void ssl_hook_Insert_Filter(request_rec *r)
-{
- SSLSrvConfigRec *sc = mySrvConfig(r->server);
-
- if (sc->enabled == SSL_ENABLED_OPTIONAL) {
- ap_add_output_filter("UPGRADE_FILTER", NULL, r, r->connection);
- }
+ return ssl_init_ssl_connection(c, NULL);
}
/*
@@ -526,20 +551,30 @@ static void ssl_register_hooks(apr_pool_t *p)
ap_hook_default_port (ssl_hook_default_port, NULL,NULL, APR_HOOK_MIDDLE);
ap_hook_pre_config (ssl_hook_pre_config, NULL,NULL, APR_HOOK_MIDDLE);
ap_hook_child_init (ssl_init_Child, NULL,NULL, APR_HOOK_MIDDLE);
- ap_hook_check_user_id (ssl_hook_UserCheck, NULL,NULL, APR_HOOK_FIRST);
+ ap_hook_check_authn (ssl_hook_UserCheck, NULL,NULL, APR_HOOK_FIRST,
+ AP_AUTH_INTERNAL_PER_CONF);
ap_hook_fixups (ssl_hook_Fixup, NULL,NULL, APR_HOOK_MIDDLE);
- ap_hook_access_checker(ssl_hook_Access, NULL,NULL, APR_HOOK_MIDDLE);
- ap_hook_auth_checker (ssl_hook_Auth, NULL,NULL, APR_HOOK_MIDDLE);
+ ap_hook_check_access (ssl_hook_Access, NULL,NULL, APR_HOOK_MIDDLE,
+ AP_AUTH_INTERNAL_PER_CONF);
+ ap_hook_check_authz (ssl_hook_Auth, NULL,NULL, APR_HOOK_MIDDLE,
+ AP_AUTH_INTERNAL_PER_CONF);
ap_hook_post_read_request(ssl_hook_ReadReq, pre_prr,NULL, APR_HOOK_MIDDLE);
- ap_hook_insert_filter (ssl_hook_Insert_Filter, NULL,NULL, APR_HOOK_MIDDLE);
-/* ap_hook_handler (ssl_hook_Upgrade, NULL,NULL, APR_HOOK_MIDDLE); */
ssl_var_register(p);
APR_REGISTER_OPTIONAL_FN(ssl_proxy_enable);
APR_REGISTER_OPTIONAL_FN(ssl_engine_disable);
- APR_REGISTER_OPTIONAL_FN(ssl_extlist_by_oid);
+ ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ssl",
+ AUTHZ_PROVIDER_VERSION,
+ &ssl_authz_provider_require_ssl,
+ AP_AUTH_INTERNAL_PER_CONF);
+
+ ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ssl-verify-client",
+ AUTHZ_PROVIDER_VERSION,
+ &ssl_authz_provider_verify_client,
+ AP_AUTH_INTERNAL_PER_CONF);
+
}
module AP_MODULE_DECLARE_DATA ssl_module = {
diff --git a/modules/ssl/mod_ssl.dep b/modules/ssl/mod_ssl.dep
deleted file mode 100644
index 9256241a..00000000
--- a/modules/ssl/mod_ssl.dep
+++ /dev/null
@@ -1,1017 +0,0 @@
-# Microsoft Developer Studio Generated Dependency File, included by mod_ssl.mak
-
-.\mod_ssl.c : \
- "..\..\include\ap_config.h"\
- "..\..\include\ap_mmn.h"\
- "..\..\include\ap_regex.h"\
- "..\..\include\ap_release.h"\
- "..\..\include\http_config.h"\
- "..\..\include\http_connection.h"\
- "..\..\include\http_core.h"\
- "..\..\include\http_log.h"\
- "..\..\include\http_main.h"\
- "..\..\include\http_protocol.h"\
- "..\..\include\http_request.h"\
- "..\..\include\http_vhost.h"\
- "..\..\include\httpd.h"\
- "..\..\include\mpm.h"\
- "..\..\include\os.h"\
- "..\..\include\scoreboard.h"\
- "..\..\include\util_cfgtree.h"\
- "..\..\include\util_charset.h"\
- "..\..\include\util_ebcdic.h"\
- "..\..\include\util_filter.h"\
- "..\..\include\util_md5.h"\
- "..\..\include\util_script.h"\
- "..\..\srclib\apr-util\include\apr_dbm.h"\
- "..\..\srclib\apr-util\include\apr_hooks.h"\
- "..\..\srclib\apr-util\include\apr_md5.h"\
- "..\..\srclib\apr-util\include\apr_optional.h"\
- "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
- "..\..\srclib\apr-util\include\apr_rmm.h"\
- "..\..\srclib\apr-util\include\apr_uri.h"\
- "..\..\srclib\apr\include\apr_fnmatch.h"\
- "..\..\srclib\apr\include\apr_hash.h"\
- "..\..\srclib\apr\include\apr_lib.h"\
- "..\..\srclib\apr\include\apr_mmap.h"\
- "..\..\srclib\apr\include\apr_poll.h"\
- "..\..\srclib\apr\include\apr_portable.h"\
- "..\..\srclib\apr\include\apr_strings.h"\
- "..\..\srclib\apr\include\apr_thread_rwlock.h"\
- "..\..\srclib\openssl\inc32\openssl\conf.h"\
- "..\..\srclib\openssl\inc32\openssl\engine.h"\
- "..\..\srclib\openssl\inc32\openssl\store.h"\
- "..\..\srclib\openssl\inc32\openssl\ui.h"\
- "..\..\srclib\openssl\inc32\openssl\x509v3.h"\
- ".\mod_ssl.h"\
- ".\ssl_expr.h"\
- ".\ssl_private.h"\
- ".\ssl_toolkit_compat.h"\
- ".\ssl_util_ssl.h"\
-
-
-.\ssl_engine_config.c : \
- "..\..\include\ap_config.h"\
- "..\..\include\ap_mmn.h"\
- "..\..\include\ap_regex.h"\
- "..\..\include\ap_release.h"\
- "..\..\include\http_config.h"\
- "..\..\include\http_connection.h"\
- "..\..\include\http_core.h"\
- "..\..\include\http_log.h"\
- "..\..\include\http_main.h"\
- "..\..\include\http_protocol.h"\
- "..\..\include\http_request.h"\
- "..\..\include\http_vhost.h"\
- "..\..\include\httpd.h"\
- "..\..\include\mpm.h"\
- "..\..\include\os.h"\
- "..\..\include\scoreboard.h"\
- "..\..\include\util_cfgtree.h"\
- "..\..\include\util_charset.h"\
- "..\..\include\util_ebcdic.h"\
- "..\..\include\util_filter.h"\
- "..\..\include\util_script.h"\
- "..\..\srclib\apr-util\include\apr_dbm.h"\
- "..\..\srclib\apr-util\include\apr_hooks.h"\
- "..\..\srclib\apr-util\include\apr_optional.h"\
- "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
- "..\..\srclib\apr-util\include\apr_rmm.h"\
- "..\..\srclib\apr-util\include\apr_uri.h"\
- "..\..\srclib\apr\include\apr_fnmatch.h"\
- "..\..\srclib\apr\include\apr_hash.h"\
- "..\..\srclib\apr\include\apr_lib.h"\
- "..\..\srclib\apr\include\apr_mmap.h"\
- "..\..\srclib\apr\include\apr_poll.h"\
- "..\..\srclib\apr\include\apr_portable.h"\
- "..\..\srclib\apr\include\apr_strings.h"\
- "..\..\srclib\apr\include\apr_thread_rwlock.h"\
- "..\..\srclib\openssl\inc32\openssl\conf.h"\
- "..\..\srclib\openssl\inc32\openssl\engine.h"\
- "..\..\srclib\openssl\inc32\openssl\store.h"\
- "..\..\srclib\openssl\inc32\openssl\ui.h"\
- "..\..\srclib\openssl\inc32\openssl\x509v3.h"\
- ".\ssl_expr.h"\
- ".\ssl_private.h"\
- ".\ssl_toolkit_compat.h"\
- ".\ssl_util_ssl.h"\
-
-
-.\ssl_engine_dh.c : \
- "..\..\include\ap_config.h"\
- "..\..\include\ap_mmn.h"\
- "..\..\include\ap_regex.h"\
- "..\..\include\ap_release.h"\
- "..\..\include\http_config.h"\
- "..\..\include\http_connection.h"\
- "..\..\include\http_core.h"\
- "..\..\include\http_log.h"\
- "..\..\include\http_main.h"\
- "..\..\include\http_protocol.h"\
- "..\..\include\http_request.h"\
- "..\..\include\http_vhost.h"\
- "..\..\include\httpd.h"\
- "..\..\include\mpm.h"\
- "..\..\include\os.h"\
- "..\..\include\scoreboard.h"\
- "..\..\include\util_cfgtree.h"\
- "..\..\include\util_charset.h"\
- "..\..\include\util_ebcdic.h"\
- "..\..\include\util_filter.h"\
- "..\..\include\util_script.h"\
- "..\..\srclib\apr-util\include\apr_dbm.h"\
- "..\..\srclib\apr-util\include\apr_hooks.h"\
- "..\..\srclib\apr-util\include\apr_optional.h"\
- "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
- "..\..\srclib\apr-util\include\apr_rmm.h"\
- "..\..\srclib\apr-util\include\apr_uri.h"\
- "..\..\srclib\apr\include\apr_fnmatch.h"\
- "..\..\srclib\apr\include\apr_hash.h"\
- "..\..\srclib\apr\include\apr_lib.h"\
- "..\..\srclib\apr\include\apr_mmap.h"\
- "..\..\srclib\apr\include\apr_poll.h"\
- "..\..\srclib\apr\include\apr_portable.h"\
- "..\..\srclib\apr\include\apr_strings.h"\
- "..\..\srclib\apr\include\apr_thread_rwlock.h"\
- "..\..\srclib\openssl\inc32\openssl\conf.h"\
- "..\..\srclib\openssl\inc32\openssl\engine.h"\
- "..\..\srclib\openssl\inc32\openssl\store.h"\
- "..\..\srclib\openssl\inc32\openssl\ui.h"\
- "..\..\srclib\openssl\inc32\openssl\x509v3.h"\
- ".\ssl_expr.h"\
- ".\ssl_private.h"\
- ".\ssl_toolkit_compat.h"\
- ".\ssl_util_ssl.h"\
-
-
-.\ssl_engine_init.c : \
- "..\..\include\ap_config.h"\
- "..\..\include\ap_mmn.h"\
- "..\..\include\ap_regex.h"\
- "..\..\include\ap_release.h"\
- "..\..\include\http_config.h"\
- "..\..\include\http_connection.h"\
- "..\..\include\http_core.h"\
- "..\..\include\http_log.h"\
- "..\..\include\http_main.h"\
- "..\..\include\http_protocol.h"\
- "..\..\include\http_request.h"\
- "..\..\include\http_vhost.h"\
- "..\..\include\httpd.h"\
- "..\..\include\mpm.h"\
- "..\..\include\os.h"\
- "..\..\include\scoreboard.h"\
- "..\..\include\util_cfgtree.h"\
- "..\..\include\util_charset.h"\
- "..\..\include\util_ebcdic.h"\
- "..\..\include\util_filter.h"\
- "..\..\include\util_script.h"\
- "..\..\srclib\apr-util\include\apr_dbm.h"\
- "..\..\srclib\apr-util\include\apr_hooks.h"\
- "..\..\srclib\apr-util\include\apr_optional.h"\
- "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
- "..\..\srclib\apr-util\include\apr_rmm.h"\
- "..\..\srclib\apr-util\include\apr_uri.h"\
- "..\..\srclib\apr\include\apr_fnmatch.h"\
- "..\..\srclib\apr\include\apr_hash.h"\
- "..\..\srclib\apr\include\apr_lib.h"\
- "..\..\srclib\apr\include\apr_mmap.h"\
- "..\..\srclib\apr\include\apr_poll.h"\
- "..\..\srclib\apr\include\apr_portable.h"\
- "..\..\srclib\apr\include\apr_strings.h"\
- "..\..\srclib\apr\include\apr_thread_rwlock.h"\
- "..\..\srclib\openssl\inc32\openssl\conf.h"\
- "..\..\srclib\openssl\inc32\openssl\engine.h"\
- "..\..\srclib\openssl\inc32\openssl\store.h"\
- "..\..\srclib\openssl\inc32\openssl\ui.h"\
- "..\..\srclib\openssl\inc32\openssl\x509v3.h"\
- ".\ssl_expr.h"\
- ".\ssl_private.h"\
- ".\ssl_toolkit_compat.h"\
- ".\ssl_util_ssl.h"\
-
-
-.\ssl_engine_io.c : \
- "..\..\include\ap_config.h"\
- "..\..\include\ap_mmn.h"\
- "..\..\include\ap_regex.h"\
- "..\..\include\ap_release.h"\
- "..\..\include\http_config.h"\
- "..\..\include\http_connection.h"\
- "..\..\include\http_core.h"\
- "..\..\include\http_log.h"\
- "..\..\include\http_main.h"\
- "..\..\include\http_protocol.h"\
- "..\..\include\http_request.h"\
- "..\..\include\http_vhost.h"\
- "..\..\include\httpd.h"\
- "..\..\include\mpm.h"\
- "..\..\include\os.h"\
- "..\..\include\scoreboard.h"\
- "..\..\include\util_cfgtree.h"\
- "..\..\include\util_charset.h"\
- "..\..\include\util_ebcdic.h"\
- "..\..\include\util_filter.h"\
- "..\..\include\util_script.h"\
- "..\..\srclib\apr-util\include\apr_date.h"\
- "..\..\srclib\apr-util\include\apr_dbm.h"\
- "..\..\srclib\apr-util\include\apr_hooks.h"\
- "..\..\srclib\apr-util\include\apr_optional.h"\
- "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
- "..\..\srclib\apr-util\include\apr_rmm.h"\
- "..\..\srclib\apr-util\include\apr_uri.h"\
- "..\..\srclib\apr\include\apr_fnmatch.h"\
- "..\..\srclib\apr\include\apr_hash.h"\
- "..\..\srclib\apr\include\apr_lib.h"\
- "..\..\srclib\apr\include\apr_mmap.h"\
- "..\..\srclib\apr\include\apr_poll.h"\
- "..\..\srclib\apr\include\apr_portable.h"\
- "..\..\srclib\apr\include\apr_strings.h"\
- "..\..\srclib\apr\include\apr_thread_rwlock.h"\
- "..\..\srclib\openssl\inc32\openssl\conf.h"\
- "..\..\srclib\openssl\inc32\openssl\engine.h"\
- "..\..\srclib\openssl\inc32\openssl\store.h"\
- "..\..\srclib\openssl\inc32\openssl\ui.h"\
- "..\..\srclib\openssl\inc32\openssl\x509v3.h"\
- ".\ssl_expr.h"\
- ".\ssl_private.h"\
- ".\ssl_toolkit_compat.h"\
- ".\ssl_util_ssl.h"\
-
-
-.\ssl_engine_kernel.c : \
- "..\..\include\ap_config.h"\
- "..\..\include\ap_mmn.h"\
- "..\..\include\ap_regex.h"\
- "..\..\include\ap_release.h"\
- "..\..\include\http_config.h"\
- "..\..\include\http_connection.h"\
- "..\..\include\http_core.h"\
- "..\..\include\http_log.h"\
- "..\..\include\http_main.h"\
- "..\..\include\http_protocol.h"\
- "..\..\include\http_request.h"\
- "..\..\include\http_vhost.h"\
- "..\..\include\httpd.h"\
- "..\..\include\mpm.h"\
- "..\..\include\os.h"\
- "..\..\include\scoreboard.h"\
- "..\..\include\util_cfgtree.h"\
- "..\..\include\util_charset.h"\
- "..\..\include\util_ebcdic.h"\
- "..\..\include\util_filter.h"\
- "..\..\include\util_script.h"\
- "..\..\srclib\apr-util\include\apr_dbm.h"\
- "..\..\srclib\apr-util\include\apr_hooks.h"\
- "..\..\srclib\apr-util\include\apr_optional.h"\
- "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
- "..\..\srclib\apr-util\include\apr_rmm.h"\
- "..\..\srclib\apr-util\include\apr_uri.h"\
- "..\..\srclib\apr\include\apr_fnmatch.h"\
- "..\..\srclib\apr\include\apr_hash.h"\
- "..\..\srclib\apr\include\apr_lib.h"\
- "..\..\srclib\apr\include\apr_mmap.h"\
- "..\..\srclib\apr\include\apr_poll.h"\
- "..\..\srclib\apr\include\apr_portable.h"\
- "..\..\srclib\apr\include\apr_strings.h"\
- "..\..\srclib\apr\include\apr_thread_rwlock.h"\
- "..\..\srclib\openssl\inc32\openssl\conf.h"\
- "..\..\srclib\openssl\inc32\openssl\engine.h"\
- "..\..\srclib\openssl\inc32\openssl\store.h"\
- "..\..\srclib\openssl\inc32\openssl\ui.h"\
- "..\..\srclib\openssl\inc32\openssl\x509v3.h"\
- ".\ssl_expr.h"\
- ".\ssl_private.h"\
- ".\ssl_toolkit_compat.h"\
- ".\ssl_util_ssl.h"\
-
-
-.\ssl_engine_log.c : \
- "..\..\include\ap_config.h"\
- "..\..\include\ap_mmn.h"\
- "..\..\include\ap_regex.h"\
- "..\..\include\ap_release.h"\
- "..\..\include\http_config.h"\
- "..\..\include\http_connection.h"\
- "..\..\include\http_core.h"\
- "..\..\include\http_log.h"\
- "..\..\include\http_main.h"\
- "..\..\include\http_protocol.h"\
- "..\..\include\http_request.h"\
- "..\..\include\http_vhost.h"\
- "..\..\include\httpd.h"\
- "..\..\include\mpm.h"\
- "..\..\include\os.h"\
- "..\..\include\scoreboard.h"\
- "..\..\include\util_cfgtree.h"\
- "..\..\include\util_charset.h"\
- "..\..\include\util_ebcdic.h"\
- "..\..\include\util_filter.h"\
- "..\..\include\util_script.h"\
- "..\..\srclib\apr-util\include\apr_dbm.h"\
- "..\..\srclib\apr-util\include\apr_hooks.h"\
- "..\..\srclib\apr-util\include\apr_optional.h"\
- "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
- "..\..\srclib\apr-util\include\apr_rmm.h"\
- "..\..\srclib\apr-util\include\apr_uri.h"\
- "..\..\srclib\apr\include\apr_fnmatch.h"\
- "..\..\srclib\apr\include\apr_hash.h"\
- "..\..\srclib\apr\include\apr_lib.h"\
- "..\..\srclib\apr\include\apr_mmap.h"\
- "..\..\srclib\apr\include\apr_poll.h"\
- "..\..\srclib\apr\include\apr_portable.h"\
- "..\..\srclib\apr\include\apr_strings.h"\
- "..\..\srclib\apr\include\apr_thread_rwlock.h"\
- "..\..\srclib\openssl\inc32\openssl\conf.h"\
- "..\..\srclib\openssl\inc32\openssl\engine.h"\
- "..\..\srclib\openssl\inc32\openssl\store.h"\
- "..\..\srclib\openssl\inc32\openssl\ui.h"\
- "..\..\srclib\openssl\inc32\openssl\x509v3.h"\
- ".\ssl_expr.h"\
- ".\ssl_private.h"\
- ".\ssl_toolkit_compat.h"\
- ".\ssl_util_ssl.h"\
-
-
-.\ssl_engine_mutex.c : \
- "..\..\include\ap_config.h"\
- "..\..\include\ap_mmn.h"\
- "..\..\include\ap_regex.h"\
- "..\..\include\ap_release.h"\
- "..\..\include\http_config.h"\
- "..\..\include\http_connection.h"\
- "..\..\include\http_core.h"\
- "..\..\include\http_log.h"\
- "..\..\include\http_main.h"\
- "..\..\include\http_protocol.h"\
- "..\..\include\http_request.h"\
- "..\..\include\http_vhost.h"\
- "..\..\include\httpd.h"\
- "..\..\include\mpm.h"\
- "..\..\include\os.h"\
- "..\..\include\scoreboard.h"\
- "..\..\include\util_cfgtree.h"\
- "..\..\include\util_charset.h"\
- "..\..\include\util_ebcdic.h"\
- "..\..\include\util_filter.h"\
- "..\..\include\util_script.h"\
- "..\..\srclib\apr-util\include\apr_dbm.h"\
- "..\..\srclib\apr-util\include\apr_hooks.h"\
- "..\..\srclib\apr-util\include\apr_optional.h"\
- "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
- "..\..\srclib\apr-util\include\apr_rmm.h"\
- "..\..\srclib\apr-util\include\apr_uri.h"\
- "..\..\srclib\apr\include\apr_fnmatch.h"\
- "..\..\srclib\apr\include\apr_hash.h"\
- "..\..\srclib\apr\include\apr_lib.h"\
- "..\..\srclib\apr\include\apr_mmap.h"\
- "..\..\srclib\apr\include\apr_poll.h"\
- "..\..\srclib\apr\include\apr_portable.h"\
- "..\..\srclib\apr\include\apr_strings.h"\
- "..\..\srclib\apr\include\apr_thread_rwlock.h"\
- "..\..\srclib\openssl\inc32\openssl\conf.h"\
- "..\..\srclib\openssl\inc32\openssl\engine.h"\
- "..\..\srclib\openssl\inc32\openssl\store.h"\
- "..\..\srclib\openssl\inc32\openssl\ui.h"\
- "..\..\srclib\openssl\inc32\openssl\x509v3.h"\
- ".\ssl_expr.h"\
- ".\ssl_private.h"\
- ".\ssl_toolkit_compat.h"\
- ".\ssl_util_ssl.h"\
-
-
-.\ssl_engine_pphrase.c : \
- "..\..\include\ap_config.h"\
- "..\..\include\ap_mmn.h"\
- "..\..\include\ap_regex.h"\
- "..\..\include\ap_release.h"\
- "..\..\include\http_config.h"\
- "..\..\include\http_connection.h"\
- "..\..\include\http_core.h"\
- "..\..\include\http_log.h"\
- "..\..\include\http_main.h"\
- "..\..\include\http_protocol.h"\
- "..\..\include\http_request.h"\
- "..\..\include\http_vhost.h"\
- "..\..\include\httpd.h"\
- "..\..\include\mpm.h"\
- "..\..\include\os.h"\
- "..\..\include\scoreboard.h"\
- "..\..\include\util_cfgtree.h"\
- "..\..\include\util_charset.h"\
- "..\..\include\util_ebcdic.h"\
- "..\..\include\util_filter.h"\
- "..\..\include\util_script.h"\
- "..\..\srclib\apr-util\include\apr_dbm.h"\
- "..\..\srclib\apr-util\include\apr_hooks.h"\
- "..\..\srclib\apr-util\include\apr_optional.h"\
- "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
- "..\..\srclib\apr-util\include\apr_rmm.h"\
- "..\..\srclib\apr-util\include\apr_uri.h"\
- "..\..\srclib\apr\include\apr_fnmatch.h"\
- "..\..\srclib\apr\include\apr_hash.h"\
- "..\..\srclib\apr\include\apr_lib.h"\
- "..\..\srclib\apr\include\apr_mmap.h"\
- "..\..\srclib\apr\include\apr_poll.h"\
- "..\..\srclib\apr\include\apr_portable.h"\
- "..\..\srclib\apr\include\apr_strings.h"\
- "..\..\srclib\apr\include\apr_thread_rwlock.h"\
- "..\..\srclib\openssl\inc32\openssl\conf.h"\
- "..\..\srclib\openssl\inc32\openssl\engine.h"\
- "..\..\srclib\openssl\inc32\openssl\store.h"\
- "..\..\srclib\openssl\inc32\openssl\ui.h"\
- "..\..\srclib\openssl\inc32\openssl\x509v3.h"\
- ".\ssl_expr.h"\
- ".\ssl_private.h"\
- ".\ssl_toolkit_compat.h"\
- ".\ssl_util_ssl.h"\
-
-
-.\ssl_engine_rand.c : \
- "..\..\include\ap_config.h"\
- "..\..\include\ap_mmn.h"\
- "..\..\include\ap_regex.h"\
- "..\..\include\ap_release.h"\
- "..\..\include\http_config.h"\
- "..\..\include\http_connection.h"\
- "..\..\include\http_core.h"\
- "..\..\include\http_log.h"\
- "..\..\include\http_main.h"\
- "..\..\include\http_protocol.h"\
- "..\..\include\http_request.h"\
- "..\..\include\http_vhost.h"\
- "..\..\include\httpd.h"\
- "..\..\include\mpm.h"\
- "..\..\include\os.h"\
- "..\..\include\scoreboard.h"\
- "..\..\include\util_cfgtree.h"\
- "..\..\include\util_charset.h"\
- "..\..\include\util_ebcdic.h"\
- "..\..\include\util_filter.h"\
- "..\..\include\util_script.h"\
- "..\..\srclib\apr-util\include\apr_dbm.h"\
- "..\..\srclib\apr-util\include\apr_hooks.h"\
- "..\..\srclib\apr-util\include\apr_optional.h"\
- "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
- "..\..\srclib\apr-util\include\apr_rmm.h"\
- "..\..\srclib\apr-util\include\apr_uri.h"\
- "..\..\srclib\apr\include\apr_fnmatch.h"\
- "..\..\srclib\apr\include\apr_hash.h"\
- "..\..\srclib\apr\include\apr_lib.h"\
- "..\..\srclib\apr\include\apr_mmap.h"\
- "..\..\srclib\apr\include\apr_poll.h"\
- "..\..\srclib\apr\include\apr_portable.h"\
- "..\..\srclib\apr\include\apr_strings.h"\
- "..\..\srclib\apr\include\apr_thread_rwlock.h"\
- "..\..\srclib\openssl\inc32\openssl\conf.h"\
- "..\..\srclib\openssl\inc32\openssl\engine.h"\
- "..\..\srclib\openssl\inc32\openssl\store.h"\
- "..\..\srclib\openssl\inc32\openssl\ui.h"\
- "..\..\srclib\openssl\inc32\openssl\x509v3.h"\
- ".\ssl_expr.h"\
- ".\ssl_private.h"\
- ".\ssl_toolkit_compat.h"\
- ".\ssl_util_ssl.h"\
-
-
-.\ssl_engine_vars.c : \
- "..\..\include\ap_config.h"\
- "..\..\include\ap_mmn.h"\
- "..\..\include\ap_regex.h"\
- "..\..\include\ap_release.h"\
- "..\..\include\http_config.h"\
- "..\..\include\http_connection.h"\
- "..\..\include\http_core.h"\
- "..\..\include\http_log.h"\
- "..\..\include\http_main.h"\
- "..\..\include\http_protocol.h"\
- "..\..\include\http_request.h"\
- "..\..\include\http_vhost.h"\
- "..\..\include\httpd.h"\
- "..\..\include\mpm.h"\
- "..\..\include\os.h"\
- "..\..\include\scoreboard.h"\
- "..\..\include\util_cfgtree.h"\
- "..\..\include\util_charset.h"\
- "..\..\include\util_ebcdic.h"\
- "..\..\include\util_filter.h"\
- "..\..\include\util_script.h"\
- "..\..\srclib\apr-util\include\apr_dbm.h"\
- "..\..\srclib\apr-util\include\apr_hooks.h"\
- "..\..\srclib\apr-util\include\apr_optional.h"\
- "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
- "..\..\srclib\apr-util\include\apr_rmm.h"\
- "..\..\srclib\apr-util\include\apr_uri.h"\
- "..\..\srclib\apr\include\apr_fnmatch.h"\
- "..\..\srclib\apr\include\apr_hash.h"\
- "..\..\srclib\apr\include\apr_lib.h"\
- "..\..\srclib\apr\include\apr_mmap.h"\
- "..\..\srclib\apr\include\apr_poll.h"\
- "..\..\srclib\apr\include\apr_portable.h"\
- "..\..\srclib\apr\include\apr_strings.h"\
- "..\..\srclib\apr\include\apr_thread_rwlock.h"\
- "..\..\srclib\openssl\inc32\openssl\conf.h"\
- "..\..\srclib\openssl\inc32\openssl\engine.h"\
- "..\..\srclib\openssl\inc32\openssl\store.h"\
- "..\..\srclib\openssl\inc32\openssl\ui.h"\
- "..\..\srclib\openssl\inc32\openssl\x509v3.h"\
- "..\loggers\mod_log_config.h"\
- ".\mod_ssl.h"\
- ".\ssl_expr.h"\
- ".\ssl_private.h"\
- ".\ssl_toolkit_compat.h"\
- ".\ssl_util_ssl.h"\
-
-
-.\ssl_expr.c : \
- "..\..\include\ap_config.h"\
- "..\..\include\ap_mmn.h"\
- "..\..\include\ap_regex.h"\
- "..\..\include\ap_release.h"\
- "..\..\include\http_config.h"\
- "..\..\include\http_connection.h"\
- "..\..\include\http_core.h"\
- "..\..\include\http_log.h"\
- "..\..\include\http_main.h"\
- "..\..\include\http_protocol.h"\
- "..\..\include\http_request.h"\
- "..\..\include\http_vhost.h"\
- "..\..\include\httpd.h"\
- "..\..\include\mpm.h"\
- "..\..\include\os.h"\
- "..\..\include\scoreboard.h"\
- "..\..\include\util_cfgtree.h"\
- "..\..\include\util_charset.h"\
- "..\..\include\util_ebcdic.h"\
- "..\..\include\util_filter.h"\
- "..\..\include\util_script.h"\
- "..\..\srclib\apr-util\include\apr_dbm.h"\
- "..\..\srclib\apr-util\include\apr_hooks.h"\
- "..\..\srclib\apr-util\include\apr_optional.h"\
- "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
- "..\..\srclib\apr-util\include\apr_rmm.h"\
- "..\..\srclib\apr-util\include\apr_uri.h"\
- "..\..\srclib\apr\include\apr_fnmatch.h"\
- "..\..\srclib\apr\include\apr_hash.h"\
- "..\..\srclib\apr\include\apr_lib.h"\
- "..\..\srclib\apr\include\apr_mmap.h"\
- "..\..\srclib\apr\include\apr_poll.h"\
- "..\..\srclib\apr\include\apr_portable.h"\
- "..\..\srclib\apr\include\apr_strings.h"\
- "..\..\srclib\apr\include\apr_thread_rwlock.h"\
- "..\..\srclib\openssl\inc32\openssl\conf.h"\
- "..\..\srclib\openssl\inc32\openssl\engine.h"\
- "..\..\srclib\openssl\inc32\openssl\store.h"\
- "..\..\srclib\openssl\inc32\openssl\ui.h"\
- "..\..\srclib\openssl\inc32\openssl\x509v3.h"\
- ".\ssl_expr.h"\
- ".\ssl_private.h"\
- ".\ssl_toolkit_compat.h"\
- ".\ssl_util_ssl.h"\
-
-
-.\ssl_expr_eval.c : \
- "..\..\include\ap_config.h"\
- "..\..\include\ap_mmn.h"\
- "..\..\include\ap_regex.h"\
- "..\..\include\ap_release.h"\
- "..\..\include\http_config.h"\
- "..\..\include\http_connection.h"\
- "..\..\include\http_core.h"\
- "..\..\include\http_log.h"\
- "..\..\include\http_main.h"\
- "..\..\include\http_protocol.h"\
- "..\..\include\http_request.h"\
- "..\..\include\http_vhost.h"\
- "..\..\include\httpd.h"\
- "..\..\include\mpm.h"\
- "..\..\include\os.h"\
- "..\..\include\scoreboard.h"\
- "..\..\include\util_cfgtree.h"\
- "..\..\include\util_charset.h"\
- "..\..\include\util_ebcdic.h"\
- "..\..\include\util_filter.h"\
- "..\..\include\util_script.h"\
- "..\..\srclib\apr-util\include\apr_dbm.h"\
- "..\..\srclib\apr-util\include\apr_hooks.h"\
- "..\..\srclib\apr-util\include\apr_optional.h"\
- "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
- "..\..\srclib\apr-util\include\apr_rmm.h"\
- "..\..\srclib\apr-util\include\apr_uri.h"\
- "..\..\srclib\apr\include\apr_fnmatch.h"\
- "..\..\srclib\apr\include\apr_hash.h"\
- "..\..\srclib\apr\include\apr_lib.h"\
- "..\..\srclib\apr\include\apr_mmap.h"\
- "..\..\srclib\apr\include\apr_poll.h"\
- "..\..\srclib\apr\include\apr_portable.h"\
- "..\..\srclib\apr\include\apr_strings.h"\
- "..\..\srclib\apr\include\apr_thread_rwlock.h"\
- "..\..\srclib\openssl\inc32\openssl\conf.h"\
- "..\..\srclib\openssl\inc32\openssl\engine.h"\
- "..\..\srclib\openssl\inc32\openssl\store.h"\
- "..\..\srclib\openssl\inc32\openssl\ui.h"\
- "..\..\srclib\openssl\inc32\openssl\x509v3.h"\
- ".\ssl_expr.h"\
- ".\ssl_private.h"\
- ".\ssl_toolkit_compat.h"\
- ".\ssl_util_ssl.h"\
-
-
-.\ssl_expr_parse.c : \
- "..\..\include\ap_config.h"\
- "..\..\include\ap_mmn.h"\
- "..\..\include\ap_regex.h"\
- "..\..\include\ap_release.h"\
- "..\..\include\http_config.h"\
- "..\..\include\http_connection.h"\
- "..\..\include\http_core.h"\
- "..\..\include\http_log.h"\
- "..\..\include\http_main.h"\
- "..\..\include\http_protocol.h"\
- "..\..\include\http_request.h"\
- "..\..\include\http_vhost.h"\
- "..\..\include\httpd.h"\
- "..\..\include\mpm.h"\
- "..\..\include\os.h"\
- "..\..\include\scoreboard.h"\
- "..\..\include\util_cfgtree.h"\
- "..\..\include\util_charset.h"\
- "..\..\include\util_ebcdic.h"\
- "..\..\include\util_filter.h"\
- "..\..\include\util_script.h"\
- "..\..\srclib\apr-util\include\apr_dbm.h"\
- "..\..\srclib\apr-util\include\apr_hooks.h"\
- "..\..\srclib\apr-util\include\apr_optional.h"\
- "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
- "..\..\srclib\apr-util\include\apr_rmm.h"\
- "..\..\srclib\apr-util\include\apr_uri.h"\
- "..\..\srclib\apr\include\apr_fnmatch.h"\
- "..\..\srclib\apr\include\apr_hash.h"\
- "..\..\srclib\apr\include\apr_lib.h"\
- "..\..\srclib\apr\include\apr_mmap.h"\
- "..\..\srclib\apr\include\apr_poll.h"\
- "..\..\srclib\apr\include\apr_portable.h"\
- "..\..\srclib\apr\include\apr_strings.h"\
- "..\..\srclib\apr\include\apr_thread_rwlock.h"\
- "..\..\srclib\openssl\inc32\openssl\conf.h"\
- "..\..\srclib\openssl\inc32\openssl\engine.h"\
- "..\..\srclib\openssl\inc32\openssl\store.h"\
- "..\..\srclib\openssl\inc32\openssl\ui.h"\
- "..\..\srclib\openssl\inc32\openssl\x509v3.h"\
- ".\ssl_expr.h"\
- ".\ssl_private.h"\
- ".\ssl_toolkit_compat.h"\
- ".\ssl_util_ssl.h"\
-
-
-.\ssl_expr_scan.c : \
- "..\..\include\ap_config.h"\
- "..\..\include\ap_mmn.h"\
- "..\..\include\ap_regex.h"\
- "..\..\include\ap_release.h"\
- "..\..\include\http_config.h"\
- "..\..\include\http_connection.h"\
- "..\..\include\http_core.h"\
- "..\..\include\http_log.h"\
- "..\..\include\http_main.h"\
- "..\..\include\http_protocol.h"\
- "..\..\include\http_request.h"\
- "..\..\include\http_vhost.h"\
- "..\..\include\httpd.h"\
- "..\..\include\mpm.h"\
- "..\..\include\os.h"\
- "..\..\include\scoreboard.h"\
- "..\..\include\util_cfgtree.h"\
- "..\..\include\util_charset.h"\
- "..\..\include\util_ebcdic.h"\
- "..\..\include\util_filter.h"\
- "..\..\include\util_script.h"\
- "..\..\srclib\apr-util\include\apr_dbm.h"\
- "..\..\srclib\apr-util\include\apr_hooks.h"\
- "..\..\srclib\apr-util\include\apr_optional.h"\
- "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
- "..\..\srclib\apr-util\include\apr_rmm.h"\
- "..\..\srclib\apr-util\include\apr_uri.h"\
- "..\..\srclib\apr\include\apr_fnmatch.h"\
- "..\..\srclib\apr\include\apr_hash.h"\
- "..\..\srclib\apr\include\apr_lib.h"\
- "..\..\srclib\apr\include\apr_mmap.h"\
- "..\..\srclib\apr\include\apr_poll.h"\
- "..\..\srclib\apr\include\apr_portable.h"\
- "..\..\srclib\apr\include\apr_strings.h"\
- "..\..\srclib\apr\include\apr_thread_rwlock.h"\
- "..\..\srclib\openssl\inc32\openssl\conf.h"\
- "..\..\srclib\openssl\inc32\openssl\engine.h"\
- "..\..\srclib\openssl\inc32\openssl\store.h"\
- "..\..\srclib\openssl\inc32\openssl\ui.h"\
- "..\..\srclib\openssl\inc32\openssl\x509v3.h"\
- ".\ssl_expr.h"\
- ".\ssl_expr_parse.h"\
- ".\ssl_private.h"\
- ".\ssl_toolkit_compat.h"\
- ".\ssl_util_ssl.h"\
-
-
-.\ssl_scache.c : \
- "..\..\include\ap_config.h"\
- "..\..\include\ap_mmn.h"\
- "..\..\include\ap_regex.h"\
- "..\..\include\ap_release.h"\
- "..\..\include\http_config.h"\
- "..\..\include\http_connection.h"\
- "..\..\include\http_core.h"\
- "..\..\include\http_log.h"\
- "..\..\include\http_main.h"\
- "..\..\include\http_protocol.h"\
- "..\..\include\http_request.h"\
- "..\..\include\http_vhost.h"\
- "..\..\include\httpd.h"\
- "..\..\include\mpm.h"\
- "..\..\include\os.h"\
- "..\..\include\scoreboard.h"\
- "..\..\include\util_cfgtree.h"\
- "..\..\include\util_charset.h"\
- "..\..\include\util_ebcdic.h"\
- "..\..\include\util_filter.h"\
- "..\..\include\util_script.h"\
- "..\..\srclib\apr-util\include\apr_dbm.h"\
- "..\..\srclib\apr-util\include\apr_hooks.h"\
- "..\..\srclib\apr-util\include\apr_optional.h"\
- "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
- "..\..\srclib\apr-util\include\apr_rmm.h"\
- "..\..\srclib\apr-util\include\apr_uri.h"\
- "..\..\srclib\apr\include\apr_fnmatch.h"\
- "..\..\srclib\apr\include\apr_hash.h"\
- "..\..\srclib\apr\include\apr_lib.h"\
- "..\..\srclib\apr\include\apr_mmap.h"\
- "..\..\srclib\apr\include\apr_poll.h"\
- "..\..\srclib\apr\include\apr_portable.h"\
- "..\..\srclib\apr\include\apr_strings.h"\
- "..\..\srclib\apr\include\apr_thread_rwlock.h"\
- "..\..\srclib\openssl\inc32\openssl\conf.h"\
- "..\..\srclib\openssl\inc32\openssl\engine.h"\
- "..\..\srclib\openssl\inc32\openssl\store.h"\
- "..\..\srclib\openssl\inc32\openssl\ui.h"\
- "..\..\srclib\openssl\inc32\openssl\x509v3.h"\
- "..\generators\mod_status.h"\
- ".\ssl_expr.h"\
- ".\ssl_private.h"\
- ".\ssl_toolkit_compat.h"\
- ".\ssl_util_ssl.h"\
-
-
-.\ssl_scache_dbm.c : \
- "..\..\include\ap_config.h"\
- "..\..\include\ap_mmn.h"\
- "..\..\include\ap_regex.h"\
- "..\..\include\ap_release.h"\
- "..\..\include\http_config.h"\
- "..\..\include\http_connection.h"\
- "..\..\include\http_core.h"\
- "..\..\include\http_log.h"\
- "..\..\include\http_main.h"\
- "..\..\include\http_protocol.h"\
- "..\..\include\http_request.h"\
- "..\..\include\http_vhost.h"\
- "..\..\include\httpd.h"\
- "..\..\include\mpm.h"\
- "..\..\include\os.h"\
- "..\..\include\scoreboard.h"\
- "..\..\include\util_cfgtree.h"\
- "..\..\include\util_charset.h"\
- "..\..\include\util_ebcdic.h"\
- "..\..\include\util_filter.h"\
- "..\..\include\util_script.h"\
- "..\..\srclib\apr-util\include\apr_dbm.h"\
- "..\..\srclib\apr-util\include\apr_hooks.h"\
- "..\..\srclib\apr-util\include\apr_optional.h"\
- "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
- "..\..\srclib\apr-util\include\apr_rmm.h"\
- "..\..\srclib\apr-util\include\apr_uri.h"\
- "..\..\srclib\apr\include\apr_fnmatch.h"\
- "..\..\srclib\apr\include\apr_hash.h"\
- "..\..\srclib\apr\include\apr_lib.h"\
- "..\..\srclib\apr\include\apr_mmap.h"\
- "..\..\srclib\apr\include\apr_poll.h"\
- "..\..\srclib\apr\include\apr_portable.h"\
- "..\..\srclib\apr\include\apr_strings.h"\
- "..\..\srclib\apr\include\apr_thread_rwlock.h"\
- "..\..\srclib\openssl\inc32\openssl\conf.h"\
- "..\..\srclib\openssl\inc32\openssl\engine.h"\
- "..\..\srclib\openssl\inc32\openssl\store.h"\
- "..\..\srclib\openssl\inc32\openssl\ui.h"\
- "..\..\srclib\openssl\inc32\openssl\x509v3.h"\
- ".\ssl_expr.h"\
- ".\ssl_private.h"\
- ".\ssl_toolkit_compat.h"\
- ".\ssl_util_ssl.h"\
-
-
-.\ssl_scache_dc.c : \
- "..\..\include\ap_config.h"\
- "..\..\include\ap_mmn.h"\
- "..\..\include\ap_regex.h"\
- "..\..\include\ap_release.h"\
- "..\..\include\http_config.h"\
- "..\..\include\http_connection.h"\
- "..\..\include\http_core.h"\
- "..\..\include\http_log.h"\
- "..\..\include\http_main.h"\
- "..\..\include\http_protocol.h"\
- "..\..\include\http_request.h"\
- "..\..\include\http_vhost.h"\
- "..\..\include\httpd.h"\
- "..\..\include\mpm.h"\
- "..\..\include\os.h"\
- "..\..\include\scoreboard.h"\
- "..\..\include\util_cfgtree.h"\
- "..\..\include\util_charset.h"\
- "..\..\include\util_ebcdic.h"\
- "..\..\include\util_filter.h"\
- "..\..\include\util_script.h"\
- "..\..\srclib\apr-util\include\apr_dbm.h"\
- "..\..\srclib\apr-util\include\apr_hooks.h"\
- "..\..\srclib\apr-util\include\apr_optional.h"\
- "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
- "..\..\srclib\apr-util\include\apr_rmm.h"\
- "..\..\srclib\apr-util\include\apr_uri.h"\
- "..\..\srclib\apr\include\apr_fnmatch.h"\
- "..\..\srclib\apr\include\apr_hash.h"\
- "..\..\srclib\apr\include\apr_lib.h"\
- "..\..\srclib\apr\include\apr_mmap.h"\
- "..\..\srclib\apr\include\apr_poll.h"\
- "..\..\srclib\apr\include\apr_portable.h"\
- "..\..\srclib\apr\include\apr_strings.h"\
- "..\..\srclib\apr\include\apr_thread_rwlock.h"\
- "..\..\srclib\openssl\inc32\openssl\conf.h"\
- "..\..\srclib\openssl\inc32\openssl\engine.h"\
- "..\..\srclib\openssl\inc32\openssl\store.h"\
- "..\..\srclib\openssl\inc32\openssl\ui.h"\
- "..\..\srclib\openssl\inc32\openssl\x509v3.h"\
- ".\ssl_expr.h"\
- ".\ssl_private.h"\
- ".\ssl_toolkit_compat.h"\
- ".\ssl_util_ssl.h"\
-
-
-.\ssl_scache_shmcb.c : \
- "..\..\include\ap_config.h"\
- "..\..\include\ap_mmn.h"\
- "..\..\include\ap_regex.h"\
- "..\..\include\ap_release.h"\
- "..\..\include\http_config.h"\
- "..\..\include\http_connection.h"\
- "..\..\include\http_core.h"\
- "..\..\include\http_log.h"\
- "..\..\include\http_main.h"\
- "..\..\include\http_protocol.h"\
- "..\..\include\http_request.h"\
- "..\..\include\http_vhost.h"\
- "..\..\include\httpd.h"\
- "..\..\include\mpm.h"\
- "..\..\include\os.h"\
- "..\..\include\scoreboard.h"\
- "..\..\include\util_cfgtree.h"\
- "..\..\include\util_charset.h"\
- "..\..\include\util_ebcdic.h"\
- "..\..\include\util_filter.h"\
- "..\..\include\util_script.h"\
- "..\..\srclib\apr-util\include\apr_dbm.h"\
- "..\..\srclib\apr-util\include\apr_hooks.h"\
- "..\..\srclib\apr-util\include\apr_optional.h"\
- "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
- "..\..\srclib\apr-util\include\apr_rmm.h"\
- "..\..\srclib\apr-util\include\apr_uri.h"\
- "..\..\srclib\apr\include\apr_fnmatch.h"\
- "..\..\srclib\apr\include\apr_hash.h"\
- "..\..\srclib\apr\include\apr_lib.h"\
- "..\..\srclib\apr\include\apr_mmap.h"\
- "..\..\srclib\apr\include\apr_poll.h"\
- "..\..\srclib\apr\include\apr_portable.h"\
- "..\..\srclib\apr\include\apr_strings.h"\
- "..\..\srclib\apr\include\apr_thread_rwlock.h"\
- "..\..\srclib\openssl\inc32\openssl\conf.h"\
- "..\..\srclib\openssl\inc32\openssl\engine.h"\
- "..\..\srclib\openssl\inc32\openssl\store.h"\
- "..\..\srclib\openssl\inc32\openssl\ui.h"\
- "..\..\srclib\openssl\inc32\openssl\x509v3.h"\
- ".\ssl_expr.h"\
- ".\ssl_private.h"\
- ".\ssl_toolkit_compat.h"\
- ".\ssl_util_ssl.h"\
-
-
-.\ssl_util.c : \
- "..\..\include\ap_config.h"\
- "..\..\include\ap_mmn.h"\
- "..\..\include\ap_mpm.h"\
- "..\..\include\ap_regex.h"\
- "..\..\include\ap_release.h"\
- "..\..\include\http_config.h"\
- "..\..\include\http_connection.h"\
- "..\..\include\http_core.h"\
- "..\..\include\http_log.h"\
- "..\..\include\http_main.h"\
- "..\..\include\http_protocol.h"\
- "..\..\include\http_request.h"\
- "..\..\include\http_vhost.h"\
- "..\..\include\httpd.h"\
- "..\..\include\mpm.h"\
- "..\..\include\os.h"\
- "..\..\include\scoreboard.h"\
- "..\..\include\util_cfgtree.h"\
- "..\..\include\util_charset.h"\
- "..\..\include\util_ebcdic.h"\
- "..\..\include\util_filter.h"\
- "..\..\include\util_script.h"\
- "..\..\srclib\apr-util\include\apr_dbm.h"\
- "..\..\srclib\apr-util\include\apr_hooks.h"\
- "..\..\srclib\apr-util\include\apr_optional.h"\
- "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
- "..\..\srclib\apr-util\include\apr_rmm.h"\
- "..\..\srclib\apr-util\include\apr_uri.h"\
- "..\..\srclib\apr\include\apr_fnmatch.h"\
- "..\..\srclib\apr\include\apr_hash.h"\
- "..\..\srclib\apr\include\apr_lib.h"\
- "..\..\srclib\apr\include\apr_mmap.h"\
- "..\..\srclib\apr\include\apr_poll.h"\
- "..\..\srclib\apr\include\apr_portable.h"\
- "..\..\srclib\apr\include\apr_strings.h"\
- "..\..\srclib\apr\include\apr_thread_rwlock.h"\
- "..\..\srclib\openssl\inc32\openssl\conf.h"\
- "..\..\srclib\openssl\inc32\openssl\engine.h"\
- "..\..\srclib\openssl\inc32\openssl\store.h"\
- "..\..\srclib\openssl\inc32\openssl\ui.h"\
- "..\..\srclib\openssl\inc32\openssl\x509v3.h"\
- ".\ssl_expr.h"\
- ".\ssl_private.h"\
- ".\ssl_toolkit_compat.h"\
- ".\ssl_util_ssl.h"\
-
-
-.\ssl_util_ssl.c : \
- "..\..\include\ap_config.h"\
- "..\..\include\ap_mmn.h"\
- "..\..\include\ap_regex.h"\
- "..\..\include\ap_release.h"\
- "..\..\include\http_config.h"\
- "..\..\include\http_connection.h"\
- "..\..\include\http_core.h"\
- "..\..\include\http_log.h"\
- "..\..\include\http_main.h"\
- "..\..\include\http_protocol.h"\
- "..\..\include\http_request.h"\
- "..\..\include\http_vhost.h"\
- "..\..\include\httpd.h"\
- "..\..\include\mpm.h"\
- "..\..\include\os.h"\
- "..\..\include\scoreboard.h"\
- "..\..\include\util_cfgtree.h"\
- "..\..\include\util_charset.h"\
- "..\..\include\util_ebcdic.h"\
- "..\..\include\util_filter.h"\
- "..\..\include\util_script.h"\
- "..\..\srclib\apr-util\include\apr_dbm.h"\
- "..\..\srclib\apr-util\include\apr_hooks.h"\
- "..\..\srclib\apr-util\include\apr_optional.h"\
- "..\..\srclib\apr-util\include\apr_optional_hooks.h"\
- "..\..\srclib\apr-util\include\apr_rmm.h"\
- "..\..\srclib\apr-util\include\apr_uri.h"\
- "..\..\srclib\apr\include\apr_fnmatch.h"\
- "..\..\srclib\apr\include\apr_hash.h"\
- "..\..\srclib\apr\include\apr_lib.h"\
- "..\..\srclib\apr\include\apr_mmap.h"\
- "..\..\srclib\apr\include\apr_poll.h"\
- "..\..\srclib\apr\include\apr_portable.h"\
- "..\..\srclib\apr\include\apr_strings.h"\
- "..\..\srclib\apr\include\apr_thread_rwlock.h"\
- "..\..\srclib\openssl\inc32\openssl\conf.h"\
- "..\..\srclib\openssl\inc32\openssl\engine.h"\
- "..\..\srclib\openssl\inc32\openssl\store.h"\
- "..\..\srclib\openssl\inc32\openssl\ui.h"\
- "..\..\srclib\openssl\inc32\openssl\x509v3.h"\
- ".\ssl_expr.h"\
- ".\ssl_private.h"\
- ".\ssl_toolkit_compat.h"\
- ".\ssl_util_ssl.h"\
-
-
-!IF "$(CFG)" == "mod_ssl - Win32 Release"
-
-!ELSEIF "$(CFG)" == "mod_ssl - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "mod_ssl - Win32 Lexical"
-
-!ENDIF
-
-!IF "$(CFG)" == "mod_ssl - Win32 Release"
-
-!ELSEIF "$(CFG)" == "mod_ssl - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "mod_ssl - Win32 Lexical"
-
-!ENDIF
-
-..\..\build\win32\httpd.rc : \
- "..\..\include\ap_release.h"\
-
diff --git a/modules/ssl/mod_ssl.dsp b/modules/ssl/mod_ssl.dsp
index 19aa6fb6..fc86a7b6 100644
--- a/modules/ssl/mod_ssl.dsp
+++ b/modules/ssl/mod_ssl.dsp
@@ -19,7 +19,6 @@ CFG=mod_ssl - Win32 Release
!MESSAGE
!MESSAGE "mod_ssl - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE "mod_ssl - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "mod_ssl - Win32 Lexical" (based on "Win32 (x86) Dynamic-Link Library")
!MESSAGE
# Begin Project
@@ -94,45 +93,12 @@ PostBuild_Desc=Embed .manifest
PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
# End Special Build Tool
-!ELSEIF "$(CFG)" == "mod_ssl - Win32 Lexical"
-
-# PROP BASE Use_MFC 0
-# PROP BASE Use_Debug_Libraries 0
-# PROP BASE Output_Dir "Release"
-# PROP BASE Intermediate_Dir "Release"
-# PROP BASE Target_Dir ""
-# PROP Use_MFC 0
-# PROP Use_Debug_Libraries 0
-# PROP Output_Dir "Release"
-# PROP Intermediate_Dir "Release"
-# PROP Ignore_Export_Lib 0
-# PROP Target_Dir ""
-# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /FD /c
-# ADD CPP /nologo /MD /W3 /O2 /Oy- /Zi /I "../../include" /I "../generators" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/openssl/inc32" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "WIN32_LEAN_AND_MEAN" /D "NO_IDEA" /D "NO_RC5" /D "NO_MDC2" /D "OPENSSL_NO_IDEA" /D "OPENSSL_NO_RC5" /D "OPENSSL_NO_MDC2" /D "HAVE_OPENSSL" /D "HAVE_SSL_SET_STATE" /D "HAVE_OPENSSL_ENGINE_H" /D "HAVE_ENGINE_INIT" /D "HAVE_ENGINE_LOAD_BUILTIN_ENGINES" /Fd"Release\mod_ssl_src" /FD /c
-# ADD BASE MTL /nologo /D "NDEBUG" /win32
-# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
-# ADD BASE RSC /l 0x409 /d "NDEBUG"
-# ADD RSC /l 0x409 /fo"Release/mod_ssl.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_ssl.so" /d LONG_NAME="proxy_ssl_module for Apache"
-BSC32=bscmake.exe
-# ADD BASE BSC32 /nologo
-# ADD BSC32 /nologo
-LINK32=link.exe
-# ADD BASE LINK32 kernel32.lib /nologo /subsystem:windows /dll /out:".\Release\mod_ssl.so" /base:@..\..\os\win32\BaseAddr.ref,mod_ssl.so
-# ADD LINK32 kernel32.lib user32.lib wsock32.lib ws2_32.lib advapi32.lib gdi32.lib libeay32.lib ssleay32.lib /nologo /subsystem:windows /dll /incremental:no /debug /out:".\Release\mod_ssl.so" /libpath:"../../srclib/openssl/out32dll" /libpath:"../../srclib/openssl/out32" /base:@..\..\os\win32\BaseAddr.ref,mod_ssl.so /opt:ref
-# Begin Special Build Tool
-TargetPath=.\Release\mod_ssl.so
-SOURCE="$(InputPath)"
-PostBuild_Desc=Embed .manifest
-PostBuild_Cmds=if exist $(TargetPath).manifest mt.exe -manifest $(TargetPath).manifest -outputresource:$(TargetPath);2
-# End Special Build Tool
-
!ENDIF
# Begin Target
# Name "mod_ssl - Win32 Release"
# Name "mod_ssl - Win32 Debug"
-# Name "mod_ssl - Win32 Lexical"
# Begin Group "Source Files"
# PROP Default_Filter "*.c"
@@ -182,19 +148,11 @@ SOURCE=.\ssl_engine_vars.c
# End Source File
# Begin Source File
-SOURCE=.\ssl_expr.c
+SOURCE=.\ssl_engine_ocsp.c
# End Source File
# Begin Source File
-SOURCE=.\ssl_expr_eval.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\ssl_expr_parse.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\ssl_expr_scan.c
+SOURCE=.\ssl_util_ocsp.c
# End Source File
# Begin Source File
@@ -202,15 +160,7 @@ SOURCE=.\ssl_scache.c
# End Source File
# Begin Source File
-SOURCE=.\ssl_scache_dbm.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\ssl_scache_shmcb.c
-# End Source File
-# Begin Source File
-
-SOURCE=.\ssl_scache_dc.c
+SOURCE=.\ssl_util_stapling.c
# End Source File
# Begin Source File
@@ -230,22 +180,10 @@ SOURCE=.\mod_ssl.h
# End Source File
# Begin Source File
-SOURCE=.\ssl_expr.h
-# End Source File
-# Begin Source File
-
SOURCE=.\ssl_private.h
# End Source File
# Begin Source File
-SOURCE=.\ssl_expr_parse.h
-# End Source File
-# Begin Source File
-
-SOURCE=.\ssl_toolkit_compat.h
-# End Source File
-# Begin Source File
-
SOURCE=.\ssl_util_ssl.h
# End Source File
# Begin Source File
@@ -253,73 +191,6 @@ SOURCE=.\ssl_util_ssl.h
SOURCE=.\ssl_util_table.h
# End Source File
# End Group
-# Begin Group "Generated Files"
-
-# PROP Default_Filter ""
-# Begin Source File
-
-SOURCE=.\ssl_expr_parse.y
-
-!IF "$(CFG)" == "mod_ssl - Win32 Release"
-
-# PROP Exclude_From_Build 1
-
-!ELSEIF "$(CFG)" == "mod_ssl - Win32 Debug"
-
-# PROP Exclude_From_Build 1
-
-!ELSEIF "$(CFG)" == "mod_ssl - Win32 Lexical"
-
-# PROP Ignore_Default_Tool 1
-# Begin Custom Build - Generating ssl_expr_parse.c/.h from ssl_expr_parse.y
-InputPath=.\ssl_expr_parse.y
-
-BuildCmds= \
- bison -y -d ssl_expr_parse.y \
- sed -e "s;yy;ssl_expr_yy;g" -e "/#if defined(c_plusplus) || defined(__cplusplus)/,/#endif/d" <y.tab.c >ssl_expr_parse.c \
- del y.tab.c \
- sed -e "s;yy;ssl_expr_yy;g" <y.tab.h >ssl_expr_parse.h \
- del y.tab.h
-
-"ssl_expr_parse.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
- $(BuildCmds)
-
-"ssl_expr_parse.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
- $(BuildCmds)
-# End Custom Build
-
-!ENDIF
-
-# End Source File
-# Begin Source File
-
-SOURCE=.\ssl_expr_scan.l
-
-!IF "$(CFG)" == "mod_ssl - Win32 Release"
-
-# PROP Exclude_From_Build 1
-
-!ELSEIF "$(CFG)" == "mod_ssl - Win32 Debug"
-
-# PROP Exclude_From_Build 1
-
-!ELSEIF "$(CFG)" == "mod_ssl - Win32 Lexical"
-
-# PROP Ignore_Default_Tool 1
-# Begin Custom Build - Generating ssl_expr_scan.c from ssl_expr_scan.l
-InputPath=.\ssl_expr_scan.l
-
-"ssl_expr_scan.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
- flex -Pssl_expr_yy -s -B ssl_expr_scan.l
- sed -e "/$$Header:/d" <lex.ssl_expr_yy.c >ssl_expr_scan.c
- del lex.ssl_expr_yy.c
-
-# End Custom Build
-
-!ENDIF
-
-# End Source File
-# End Group
# Begin Source File
SOURCE=..\..\build\win32\httpd.rc
diff --git a/modules/ssl/mod_ssl.h b/modules/ssl/mod_ssl.h
index ab2f90e5..48984e24 100644
--- a/modules/ssl/mod_ssl.h
+++ b/modules/ssl/mod_ssl.h
@@ -36,15 +36,20 @@ APR_DECLARE_OPTIONAL_FN(char *, ssl_var_lookup,
conn_rec *, request_rec *,
char *));
-/** The ssl_ext_lookup() optional function retrieves the value of a SSL
- * certificate X.509 extension. The client certificate is used if
- * peer is non-zero; the server certificate is used otherwise. The
- * oidnum parameter specifies the numeric OID (e.g. "1.2.3.4") of the
- * desired extension. The string value of the extension is returned,
- * or NULL on error. */
-APR_DECLARE_OPTIONAL_FN(const char *, ssl_ext_lookup,
+/** The ssl_ext_list() optional function attempts to build an array
+ * of all the values contained in the named X.509 extension. The
+ * returned array will be created in the supplied pool.
+ * The client certificate is used if peer is non-zero; the server
+ * certificate is used otherwise.
+ * Extension specifies the extensions to use as a string. This can be
+ * one of the "known" long or short names, or a numeric OID,
+ * e.g. "1.2.3.4", 'nsComment' and 'DN' are all valid.
+ * A pointer to an apr_array_header_t structure is returned if at
+ * least one matching extension is found, NULL otherwise.
+ */
+APR_DECLARE_OPTIONAL_FN(apr_array_header_t *, ssl_ext_list,
(apr_pool_t *p, conn_rec *c, int peer,
- const char *oidnum));
+ const char *extension));
/** An optional function which returns non-zero if the given connection
* is using SSL/TLS. */
@@ -58,7 +63,5 @@ APR_DECLARE_OPTIONAL_FN(int, ssl_proxy_enable, (conn_rec *));
APR_DECLARE_OPTIONAL_FN(int, ssl_engine_disable, (conn_rec *));
-APR_DECLARE_OPTIONAL_FN(apr_array_header_t *, ssl_extlist_by_oid, (request_rec *r, const char *oidstr));
-
#endif /* __MOD_SSL_H__ */
/** @} */
diff --git a/modules/ssl/mod_ssl.mak b/modules/ssl/mod_ssl.mak
deleted file mode 100644
index 003dad97..00000000
--- a/modules/ssl/mod_ssl.mak
+++ /dev/null
@@ -1,733 +0,0 @@
-# Microsoft Developer Studio Generated NMAKE File, Based on mod_ssl.dsp
-!IF "$(CFG)" == ""
-CFG=mod_ssl - Win32 Release
-!MESSAGE No configuration specified. Defaulting to mod_ssl - Win32 Release.
-!ENDIF
-
-!IF "$(CFG)" != "mod_ssl - Win32 Release" && "$(CFG)" != "mod_ssl - Win32 Debug" && "$(CFG)" != "mod_ssl - Win32 Lexical"
-!MESSAGE Invalid configuration "$(CFG)" specified.
-!MESSAGE You can specify a configuration when running NMAKE
-!MESSAGE by defining the macro CFG on the command line. For example:
-!MESSAGE
-!MESSAGE NMAKE /f "mod_ssl.mak" CFG="mod_ssl - Win32 Release"
-!MESSAGE
-!MESSAGE Possible choices for configuration are:
-!MESSAGE
-!MESSAGE "mod_ssl - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "mod_ssl - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE "mod_ssl - Win32 Lexical" (based on "Win32 (x86) Dynamic-Link Library")
-!MESSAGE
-!ERROR An invalid configuration is specified.
-!ENDIF
-
-!IF "$(OS)" == "Windows_NT"
-NULL=
-!ELSE
-NULL=nul
-!ENDIF
-
-!IF "$(CFG)" == "mod_ssl - Win32 Release"
-
-OUTDIR=.\Release
-INTDIR=.\Release
-DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
-# Begin Custom Macros
-OutDir=.\Release
-# End Custom Macros
-
-!IF "$(RECURSE)" == "0"
-
-ALL : "$(OUTDIR)\mod_ssl.so" "$(DS_POSTBUILD_DEP)"
-
-!ELSE
-
-ALL : "libhttpd - Win32 Release" "libaprutil - Win32 Release" "libapr - Win32 Release" "$(OUTDIR)\mod_ssl.so" "$(DS_POSTBUILD_DEP)"
-
-!ENDIF
-
-!IF "$(RECURSE)" == "1"
-CLEAN :"libapr - Win32 ReleaseCLEAN" "libaprutil - Win32 ReleaseCLEAN" "libhttpd - Win32 ReleaseCLEAN"
-!ELSE
-CLEAN :
-!ENDIF
- -@erase "$(INTDIR)\mod_ssl.obj"
- -@erase "$(INTDIR)\mod_ssl.res"
- -@erase "$(INTDIR)\mod_ssl_src.idb"
- -@erase "$(INTDIR)\mod_ssl_src.pdb"
- -@erase "$(INTDIR)\ssl_engine_config.obj"
- -@erase "$(INTDIR)\ssl_engine_dh.obj"
- -@erase "$(INTDIR)\ssl_engine_init.obj"
- -@erase "$(INTDIR)\ssl_engine_io.obj"
- -@erase "$(INTDIR)\ssl_engine_kernel.obj"
- -@erase "$(INTDIR)\ssl_engine_log.obj"
- -@erase "$(INTDIR)\ssl_engine_mutex.obj"
- -@erase "$(INTDIR)\ssl_engine_pphrase.obj"
- -@erase "$(INTDIR)\ssl_engine_rand.obj"
- -@erase "$(INTDIR)\ssl_engine_vars.obj"
- -@erase "$(INTDIR)\ssl_expr.obj"
- -@erase "$(INTDIR)\ssl_expr_eval.obj"
- -@erase "$(INTDIR)\ssl_expr_parse.obj"
- -@erase "$(INTDIR)\ssl_expr_scan.obj"
- -@erase "$(INTDIR)\ssl_scache.obj"
- -@erase "$(INTDIR)\ssl_scache_dbm.obj"
- -@erase "$(INTDIR)\ssl_scache_dc.obj"
- -@erase "$(INTDIR)\ssl_scache_shmcb.obj"
- -@erase "$(INTDIR)\ssl_util.obj"
- -@erase "$(INTDIR)\ssl_util_ssl.obj"
- -@erase "$(OUTDIR)\mod_ssl.exp"
- -@erase "$(OUTDIR)\mod_ssl.lib"
- -@erase "$(OUTDIR)\mod_ssl.pdb"
- -@erase "$(OUTDIR)\mod_ssl.so"
-
-"$(OUTDIR)" :
- if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
-
-CPP=cl.exe
-CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../generators" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/openssl/inc32" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "WIN32_LEAN_AND_MEAN" /D "NO_IDEA" /D "NO_RC5" /D "NO_MDC2" /D "OPENSSL_NO_IDEA" /D "OPENSSL_NO_RC5" /D "OPENSSL_NO_MDC2" /D "HAVE_OPENSSL" /D "HAVE_SSL_SET_STATE" /D "HAVE_OPENSSL_ENGINE_H" /D "HAVE_ENGINE_INIT" /D "HAVE_ENGINE_LOAD_BUILTIN_ENGINES" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_ssl_src" /FD /c
-
-.c{$(INTDIR)}.obj::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.cpp{$(INTDIR)}.obj::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.cxx{$(INTDIR)}.obj::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.c{$(INTDIR)}.sbr::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.cpp{$(INTDIR)}.sbr::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.cxx{$(INTDIR)}.sbr::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-MTL=midl.exe
-MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32
-RSC=rc.exe
-RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_ssl.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_ssl.so" /d LONG_NAME="proxy_ssl_module for Apache"
-BSC32=bscmake.exe
-BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_ssl.bsc"
-BSC32_SBRS= \
-
-LINK32=link.exe
-LINK32_FLAGS=kernel32.lib user32.lib wsock32.lib ws2_32.lib advapi32.lib gdi32.lib libeay32.lib ssleay32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_ssl.pdb" /debug /out:"$(OUTDIR)\mod_ssl.so" /implib:"$(OUTDIR)\mod_ssl.lib" /libpath:"../../srclib/openssl/out32dll" /libpath:"../../srclib/openssl/out32" /base:@..\..\os\win32\BaseAddr.ref,mod_ssl.so /opt:ref
-LINK32_OBJS= \
- "$(INTDIR)\mod_ssl.obj" \
- "$(INTDIR)\ssl_engine_config.obj" \
- "$(INTDIR)\ssl_engine_dh.obj" \
- "$(INTDIR)\ssl_engine_init.obj" \
- "$(INTDIR)\ssl_engine_io.obj" \
- "$(INTDIR)\ssl_engine_kernel.obj" \
- "$(INTDIR)\ssl_engine_log.obj" \
- "$(INTDIR)\ssl_engine_mutex.obj" \
- "$(INTDIR)\ssl_engine_pphrase.obj" \
- "$(INTDIR)\ssl_engine_rand.obj" \
- "$(INTDIR)\ssl_engine_vars.obj" \
- "$(INTDIR)\ssl_expr.obj" \
- "$(INTDIR)\ssl_expr_eval.obj" \
- "$(INTDIR)\ssl_expr_parse.obj" \
- "$(INTDIR)\ssl_expr_scan.obj" \
- "$(INTDIR)\ssl_scache.obj" \
- "$(INTDIR)\ssl_scache_dbm.obj" \
- "$(INTDIR)\ssl_scache_shmcb.obj" \
- "$(INTDIR)\ssl_scache_dc.obj" \
- "$(INTDIR)\ssl_util.obj" \
- "$(INTDIR)\ssl_util_ssl.obj" \
- "$(INTDIR)\mod_ssl.res" \
- "..\..\srclib\apr\Release\libapr-1.lib" \
- "..\..\srclib\apr-util\Release\libaprutil-1.lib" \
- "..\..\Release\libhttpd.lib"
-
-"$(OUTDIR)\mod_ssl.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
- $(LINK32) @<<
- $(LINK32_FLAGS) $(LINK32_OBJS)
-<<
-
-TargetPath=.\Release\mod_ssl.so
-SOURCE="$(InputPath)"
-PostBuild_Desc=Embed .manifest
-DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
-
-# Begin Custom Macros
-OutDir=.\Release
-# End Custom Macros
-
-"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_ssl.so"
- if exist .\Release\mod_ssl.so.manifest mt.exe -manifest .\Release\mod_ssl.so.manifest -outputresource:.\Release\mod_ssl.so;2
- echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
-
-!ELSEIF "$(CFG)" == "mod_ssl - Win32 Debug"
-
-OUTDIR=.\Debug
-INTDIR=.\Debug
-DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
-# Begin Custom Macros
-OutDir=.\Debug
-# End Custom Macros
-
-!IF "$(RECURSE)" == "0"
-
-ALL : "$(OUTDIR)\mod_ssl.so" "$(DS_POSTBUILD_DEP)"
-
-!ELSE
-
-ALL : "libhttpd - Win32 Debug" "libaprutil - Win32 Debug" "libapr - Win32 Debug" "$(OUTDIR)\mod_ssl.so" "$(DS_POSTBUILD_DEP)"
-
-!ENDIF
-
-!IF "$(RECURSE)" == "1"
-CLEAN :"libapr - Win32 DebugCLEAN" "libaprutil - Win32 DebugCLEAN" "libhttpd - Win32 DebugCLEAN"
-!ELSE
-CLEAN :
-!ENDIF
- -@erase "$(INTDIR)\mod_ssl.obj"
- -@erase "$(INTDIR)\mod_ssl.res"
- -@erase "$(INTDIR)\mod_ssl_src.idb"
- -@erase "$(INTDIR)\mod_ssl_src.pdb"
- -@erase "$(INTDIR)\ssl_engine_config.obj"
- -@erase "$(INTDIR)\ssl_engine_dh.obj"
- -@erase "$(INTDIR)\ssl_engine_init.obj"
- -@erase "$(INTDIR)\ssl_engine_io.obj"
- -@erase "$(INTDIR)\ssl_engine_kernel.obj"
- -@erase "$(INTDIR)\ssl_engine_log.obj"
- -@erase "$(INTDIR)\ssl_engine_mutex.obj"
- -@erase "$(INTDIR)\ssl_engine_pphrase.obj"
- -@erase "$(INTDIR)\ssl_engine_rand.obj"
- -@erase "$(INTDIR)\ssl_engine_vars.obj"
- -@erase "$(INTDIR)\ssl_expr.obj"
- -@erase "$(INTDIR)\ssl_expr_eval.obj"
- -@erase "$(INTDIR)\ssl_expr_parse.obj"
- -@erase "$(INTDIR)\ssl_expr_scan.obj"
- -@erase "$(INTDIR)\ssl_scache.obj"
- -@erase "$(INTDIR)\ssl_scache_dbm.obj"
- -@erase "$(INTDIR)\ssl_scache_dc.obj"
- -@erase "$(INTDIR)\ssl_scache_shmcb.obj"
- -@erase "$(INTDIR)\ssl_util.obj"
- -@erase "$(INTDIR)\ssl_util_ssl.obj"
- -@erase "$(OUTDIR)\mod_ssl.exp"
- -@erase "$(OUTDIR)\mod_ssl.lib"
- -@erase "$(OUTDIR)\mod_ssl.pdb"
- -@erase "$(OUTDIR)\mod_ssl.so"
-
-"$(OUTDIR)" :
- if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
-
-CPP=cl.exe
-CPP_PROJ=/nologo /MDd /W3 /Zi /Od /I "../../include" /I "../generators" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/openssl/inc32" /D "_DEBUG" /D "WIN32" /D "_WINDOWS" /D "WIN32_LEAN_AND_MEAN" /D "NO_IDEA" /D "NO_RC5" /D "NO_MDC2" /D "OPENSSL_NO_IDEA" /D "OPENSSL_NO_RC5" /D "OPENSSL_NO_MDC2" /D "HAVE_OPENSSL" /D "HAVE_SSL_SET_STATE" /D "HAVE_OPENSSL_ENGINE_H" /D "HAVE_ENGINE_INIT" /D "HAVE_ENGINE_LOAD_BUILTIN_ENGINES" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_ssl_src" /FD /EHsc /c
-
-.c{$(INTDIR)}.obj::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.cpp{$(INTDIR)}.obj::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.cxx{$(INTDIR)}.obj::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.c{$(INTDIR)}.sbr::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.cpp{$(INTDIR)}.sbr::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.cxx{$(INTDIR)}.sbr::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-MTL=midl.exe
-MTL_PROJ=/nologo /D "_DEBUG" /mktyplib203 /win32
-RSC=rc.exe
-RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_ssl.res" /i "../../include" /i "../../srclib/apr/include" /d "_DEBUG" /d BIN_NAME="mod_ssl.so" /d LONG_NAME="proxy_ssl_module for Apache"
-BSC32=bscmake.exe
-BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_ssl.bsc"
-BSC32_SBRS= \
-
-LINK32=link.exe
-LINK32_FLAGS=kernel32.lib user32.lib wsock32.lib ws2_32.lib advapi32.lib gdi32.lib libeay32.lib ssleay32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_ssl.pdb" /debug /out:"$(OUTDIR)\mod_ssl.so" /implib:"$(OUTDIR)\mod_ssl.lib" /libpath:"../../srclib/openssl/out32dll.dbg" /libpath:"../../srclib/openssl/out32.dbg" /libpath:"../../srclib/openssl/out32dll" /libpath:"../../srclib/openssl/out32" /base:@..\..\os\win32\BaseAddr.ref,mod_ssl.so
-LINK32_OBJS= \
- "$(INTDIR)\mod_ssl.obj" \
- "$(INTDIR)\ssl_engine_config.obj" \
- "$(INTDIR)\ssl_engine_dh.obj" \
- "$(INTDIR)\ssl_engine_init.obj" \
- "$(INTDIR)\ssl_engine_io.obj" \
- "$(INTDIR)\ssl_engine_kernel.obj" \
- "$(INTDIR)\ssl_engine_log.obj" \
- "$(INTDIR)\ssl_engine_mutex.obj" \
- "$(INTDIR)\ssl_engine_pphrase.obj" \
- "$(INTDIR)\ssl_engine_rand.obj" \
- "$(INTDIR)\ssl_engine_vars.obj" \
- "$(INTDIR)\ssl_expr.obj" \
- "$(INTDIR)\ssl_expr_eval.obj" \
- "$(INTDIR)\ssl_expr_parse.obj" \
- "$(INTDIR)\ssl_expr_scan.obj" \
- "$(INTDIR)\ssl_scache.obj" \
- "$(INTDIR)\ssl_scache_dbm.obj" \
- "$(INTDIR)\ssl_scache_shmcb.obj" \
- "$(INTDIR)\ssl_scache_dc.obj" \
- "$(INTDIR)\ssl_util.obj" \
- "$(INTDIR)\ssl_util_ssl.obj" \
- "$(INTDIR)\mod_ssl.res" \
- "..\..\srclib\apr\Debug\libapr-1.lib" \
- "..\..\srclib\apr-util\Debug\libaprutil-1.lib" \
- "..\..\Debug\libhttpd.lib"
-
-"$(OUTDIR)\mod_ssl.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
- $(LINK32) @<<
- $(LINK32_FLAGS) $(LINK32_OBJS)
-<<
-
-TargetPath=.\Debug\mod_ssl.so
-SOURCE="$(InputPath)"
-PostBuild_Desc=Embed .manifest
-DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
-
-# Begin Custom Macros
-OutDir=.\Debug
-# End Custom Macros
-
-"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_ssl.so"
- if exist .\Debug\mod_ssl.so.manifest mt.exe -manifest .\Debug\mod_ssl.so.manifest -outputresource:.\Debug\mod_ssl.so;2
- echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
-
-!ELSEIF "$(CFG)" == "mod_ssl - Win32 Lexical"
-
-OUTDIR=.\Release
-INTDIR=.\Release
-DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
-# Begin Custom Macros
-OutDir=.\Release
-# End Custom Macros
-
-!IF "$(RECURSE)" == "0"
-
-ALL : ".\ssl_expr_parse.h" ".\ssl_expr_parse.c" "$(OUTDIR)\mod_ssl.so" "$(DS_POSTBUILD_DEP)"
-
-!ELSE
-
-ALL : ".\ssl_expr_parse.h" ".\ssl_expr_parse.c" "$(OUTDIR)\mod_ssl.so" "$(DS_POSTBUILD_DEP)"
-
-!ENDIF
-
-!IF "$(RECURSE)" == "1"
-CLEAN :
-!ELSE
-CLEAN :
-!ENDIF
- -@erase "$(INTDIR)\mod_ssl.obj"
- -@erase "$(INTDIR)\mod_ssl.res"
- -@erase "$(INTDIR)\mod_ssl_src.idb"
- -@erase "$(INTDIR)\mod_ssl_src.pdb"
- -@erase "$(INTDIR)\ssl_engine_config.obj"
- -@erase "$(INTDIR)\ssl_engine_dh.obj"
- -@erase "$(INTDIR)\ssl_engine_init.obj"
- -@erase "$(INTDIR)\ssl_engine_io.obj"
- -@erase "$(INTDIR)\ssl_engine_kernel.obj"
- -@erase "$(INTDIR)\ssl_engine_log.obj"
- -@erase "$(INTDIR)\ssl_engine_mutex.obj"
- -@erase "$(INTDIR)\ssl_engine_pphrase.obj"
- -@erase "$(INTDIR)\ssl_engine_rand.obj"
- -@erase "$(INTDIR)\ssl_engine_vars.obj"
- -@erase "$(INTDIR)\ssl_expr.obj"
- -@erase "$(INTDIR)\ssl_expr_eval.obj"
- -@erase "$(INTDIR)\ssl_expr_parse.obj"
- -@erase "$(INTDIR)\ssl_expr_scan.obj"
- -@erase "$(INTDIR)\ssl_scache.obj"
- -@erase "$(INTDIR)\ssl_scache_dbm.obj"
- -@erase "$(INTDIR)\ssl_scache_dc.obj"
- -@erase "$(INTDIR)\ssl_scache_shmcb.obj"
- -@erase "$(INTDIR)\ssl_util.obj"
- -@erase "$(INTDIR)\ssl_util_ssl.obj"
- -@erase "$(OUTDIR)\mod_ssl.exp"
- -@erase "$(OUTDIR)\mod_ssl.lib"
- -@erase "$(OUTDIR)\mod_ssl.pdb"
- -@erase "$(OUTDIR)\mod_ssl.so"
- -@erase "ssl_expr_parse.c"
- -@erase "ssl_expr_parse.h"
-
-"$(OUTDIR)" :
- if not exist "$(OUTDIR)/$(NULL)" mkdir "$(OUTDIR)"
-
-CPP=cl.exe
-CPP_PROJ=/nologo /MD /W3 /Zi /O2 /Oy- /I "../../include" /I "../generators" /I "../../srclib/apr/include" /I "../../srclib/apr-util/include" /I "../../srclib/openssl/inc32" /D "NDEBUG" /D "WIN32" /D "_WINDOWS" /D "WIN32_LEAN_AND_MEAN" /D "NO_IDEA" /D "NO_RC5" /D "NO_MDC2" /D "OPENSSL_NO_IDEA" /D "OPENSSL_NO_RC5" /D "OPENSSL_NO_MDC2" /D "HAVE_OPENSSL" /D "HAVE_SSL_SET_STATE" /D "HAVE_OPENSSL_ENGINE_H" /D "HAVE_ENGINE_INIT" /D "HAVE_ENGINE_LOAD_BUILTIN_ENGINES" /Fo"$(INTDIR)\\" /Fd"$(INTDIR)\mod_ssl_src" /FD /c
-
-.c{$(INTDIR)}.obj::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.cpp{$(INTDIR)}.obj::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.cxx{$(INTDIR)}.obj::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.c{$(INTDIR)}.sbr::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.cpp{$(INTDIR)}.sbr::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-.cxx{$(INTDIR)}.sbr::
- $(CPP) @<<
- $(CPP_PROJ) $<
-<<
-
-MTL=midl.exe
-MTL_PROJ=/nologo /D "NDEBUG" /mktyplib203 /win32
-RSC=rc.exe
-RSC_PROJ=/l 0x409 /fo"$(INTDIR)\mod_ssl.res" /i "../../include" /i "../../srclib/apr/include" /d "NDEBUG" /d BIN_NAME="mod_ssl.so" /d LONG_NAME="proxy_ssl_module for Apache"
-BSC32=bscmake.exe
-BSC32_FLAGS=/nologo /o"$(OUTDIR)\mod_ssl.bsc"
-BSC32_SBRS= \
-
-LINK32=link.exe
-LINK32_FLAGS=kernel32.lib user32.lib wsock32.lib ws2_32.lib advapi32.lib gdi32.lib libeay32.lib ssleay32.lib /nologo /subsystem:windows /dll /incremental:no /pdb:"$(OUTDIR)\mod_ssl.pdb" /debug /out:"$(OUTDIR)\mod_ssl.so" /implib:"$(OUTDIR)\mod_ssl.lib" /libpath:"../../srclib/openssl/out32dll" /libpath:"../../srclib/openssl/out32" /base:@..\..\os\win32\BaseAddr.ref,mod_ssl.so /opt:ref
-LINK32_OBJS= \
- "$(INTDIR)\mod_ssl.obj" \
- "$(INTDIR)\ssl_engine_config.obj" \
- "$(INTDIR)\ssl_engine_dh.obj" \
- "$(INTDIR)\ssl_engine_init.obj" \
- "$(INTDIR)\ssl_engine_io.obj" \
- "$(INTDIR)\ssl_engine_kernel.obj" \
- "$(INTDIR)\ssl_engine_log.obj" \
- "$(INTDIR)\ssl_engine_mutex.obj" \
- "$(INTDIR)\ssl_engine_pphrase.obj" \
- "$(INTDIR)\ssl_engine_rand.obj" \
- "$(INTDIR)\ssl_engine_vars.obj" \
- "$(INTDIR)\ssl_expr.obj" \
- "$(INTDIR)\ssl_expr_eval.obj" \
- "$(INTDIR)\ssl_expr_parse.obj" \
- "$(INTDIR)\ssl_expr_scan.obj" \
- "$(INTDIR)\ssl_scache.obj" \
- "$(INTDIR)\ssl_scache_dbm.obj" \
- "$(INTDIR)\ssl_scache_shmcb.obj" \
- "$(INTDIR)\ssl_scache_dc.obj" \
- "$(INTDIR)\ssl_util.obj" \
- "$(INTDIR)\ssl_util_ssl.obj" \
- "$(INTDIR)\mod_ssl.res"
-
-"$(OUTDIR)\mod_ssl.so" : "$(OUTDIR)" $(DEF_FILE) $(LINK32_OBJS)
- $(LINK32) @<<
- $(LINK32_FLAGS) $(LINK32_OBJS)
-<<
-
-TargetPath=.\Release\mod_ssl.so
-SOURCE="$(InputPath)"
-PostBuild_Desc=Embed .manifest
-DS_POSTBUILD_DEP=$(INTDIR)\postbld.dep
-
-# Begin Custom Macros
-OutDir=.\Release
-# End Custom Macros
-
-"$(DS_POSTBUILD_DEP)" : "$(OUTDIR)\mod_ssl.so"
- if exist .\Release\mod_ssl.so.manifest mt.exe -manifest .\Release\mod_ssl.so.manifest -outputresource:.\Release\mod_ssl.so;2
- echo Helper for Post-build step > "$(DS_POSTBUILD_DEP)"
-
-!ENDIF
-
-
-!IF "$(NO_EXTERNAL_DEPS)" != "1"
-!IF EXISTS("mod_ssl.dep")
-!INCLUDE "mod_ssl.dep"
-!ELSE
-!MESSAGE Warning: cannot find "mod_ssl.dep"
-!ENDIF
-!ENDIF
-
-
-!IF "$(CFG)" == "mod_ssl - Win32 Release" || "$(CFG)" == "mod_ssl - Win32 Debug" || "$(CFG)" == "mod_ssl - Win32 Lexical"
-SOURCE=.\mod_ssl.c
-
-"$(INTDIR)\mod_ssl.obj" : $(SOURCE) "$(INTDIR)"
-
-
-SOURCE=.\ssl_engine_config.c
-
-"$(INTDIR)\ssl_engine_config.obj" : $(SOURCE) "$(INTDIR)"
-
-
-SOURCE=.\ssl_engine_dh.c
-
-"$(INTDIR)\ssl_engine_dh.obj" : $(SOURCE) "$(INTDIR)"
-
-
-SOURCE=.\ssl_engine_init.c
-
-"$(INTDIR)\ssl_engine_init.obj" : $(SOURCE) "$(INTDIR)"
-
-
-SOURCE=.\ssl_engine_io.c
-
-"$(INTDIR)\ssl_engine_io.obj" : $(SOURCE) "$(INTDIR)"
-
-
-SOURCE=.\ssl_engine_kernel.c
-
-"$(INTDIR)\ssl_engine_kernel.obj" : $(SOURCE) "$(INTDIR)"
-
-
-SOURCE=.\ssl_engine_log.c
-
-"$(INTDIR)\ssl_engine_log.obj" : $(SOURCE) "$(INTDIR)"
-
-
-SOURCE=.\ssl_engine_mutex.c
-
-"$(INTDIR)\ssl_engine_mutex.obj" : $(SOURCE) "$(INTDIR)"
-
-
-SOURCE=.\ssl_engine_pphrase.c
-
-"$(INTDIR)\ssl_engine_pphrase.obj" : $(SOURCE) "$(INTDIR)"
-
-
-SOURCE=.\ssl_engine_rand.c
-
-"$(INTDIR)\ssl_engine_rand.obj" : $(SOURCE) "$(INTDIR)"
-
-
-SOURCE=.\ssl_engine_vars.c
-
-"$(INTDIR)\ssl_engine_vars.obj" : $(SOURCE) "$(INTDIR)"
-
-
-SOURCE=.\ssl_expr.c
-
-"$(INTDIR)\ssl_expr.obj" : $(SOURCE) "$(INTDIR)"
-
-
-SOURCE=.\ssl_expr_eval.c
-
-"$(INTDIR)\ssl_expr_eval.obj" : $(SOURCE) "$(INTDIR)"
-
-
-SOURCE=.\ssl_expr_parse.c
-
-"$(INTDIR)\ssl_expr_parse.obj" : $(SOURCE) "$(INTDIR)"
-
-
-SOURCE=.\ssl_expr_scan.c
-
-"$(INTDIR)\ssl_expr_scan.obj" : $(SOURCE) "$(INTDIR)"
-
-
-SOURCE=.\ssl_scache.c
-
-"$(INTDIR)\ssl_scache.obj" : $(SOURCE) "$(INTDIR)"
-
-
-SOURCE=.\ssl_scache_dbm.c
-
-"$(INTDIR)\ssl_scache_dbm.obj" : $(SOURCE) "$(INTDIR)"
-
-
-SOURCE=.\ssl_scache_dc.c
-
-"$(INTDIR)\ssl_scache_dc.obj" : $(SOURCE) "$(INTDIR)"
-
-
-SOURCE=.\ssl_scache_shmcb.c
-
-"$(INTDIR)\ssl_scache_shmcb.obj" : $(SOURCE) "$(INTDIR)"
-
-
-SOURCE=.\ssl_util.c
-
-"$(INTDIR)\ssl_util.obj" : $(SOURCE) "$(INTDIR)"
-
-
-SOURCE=.\ssl_util_ssl.c
-
-"$(INTDIR)\ssl_util_ssl.obj" : $(SOURCE) "$(INTDIR)"
-
-
-SOURCE=.\ssl_expr_parse.y
-
-!IF "$(CFG)" == "mod_ssl - Win32 Release"
-
-!ELSEIF "$(CFG)" == "mod_ssl - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "mod_ssl - Win32 Lexical"
-
-InputPath=.\ssl_expr_parse.y
-
-".\ssl_expr_parse.c" ".\ssl_expr_parse.h" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
- <<tempfile.bat
- @echo off
- bison -y -d ssl_expr_parse.y
- sed -e "s;yy;ssl_expr_yy;g" -e "/#if defined(c_plusplus) || defined(__cplusplus)/,/#endif/d" <y.tab.c >ssl_expr_parse.c
- del y.tab.c
- sed -e "s;yy;ssl_expr_yy;g" <y.tab.h >ssl_expr_parse.h
- del y.tab.h
-<<
-
-
-!ENDIF
-
-SOURCE=.\ssl_expr_scan.l
-
-!IF "$(CFG)" == "mod_ssl - Win32 Release"
-
-!ELSEIF "$(CFG)" == "mod_ssl - Win32 Debug"
-
-!ELSEIF "$(CFG)" == "mod_ssl - Win32 Lexical"
-
-InputPath=.\ssl_expr_scan.l
-
-".\ssl_expr_scan.c" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
- <<tempfile.bat
- @echo off
- flex -Pssl_expr_yy -s -B ssl_expr_scan.l
- sed -e "/$$Header:/d" <lex.ssl_expr_yy.c >ssl_expr_scan.c
- del lex.ssl_expr_yy.c
-<<
-
-
-!ENDIF
-
-!IF "$(CFG)" == "mod_ssl - Win32 Release"
-
-"libapr - Win32 Release" :
- cd ".\..\..\srclib\apr"
- $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release"
- cd "..\..\modules\ssl"
-
-"libapr - Win32 ReleaseCLEAN" :
- cd ".\..\..\srclib\apr"
- $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Release" RECURSE=1 CLEAN
- cd "..\..\modules\ssl"
-
-!ELSEIF "$(CFG)" == "mod_ssl - Win32 Debug"
-
-"libapr - Win32 Debug" :
- cd ".\..\..\srclib\apr"
- $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug"
- cd "..\..\modules\ssl"
-
-"libapr - Win32 DebugCLEAN" :
- cd ".\..\..\srclib\apr"
- $(MAKE) /$(MAKEFLAGS) /F ".\libapr.mak" CFG="libapr - Win32 Debug" RECURSE=1 CLEAN
- cd "..\..\modules\ssl"
-
-!ELSEIF "$(CFG)" == "mod_ssl - Win32 Lexical"
-
-!ENDIF
-
-!IF "$(CFG)" == "mod_ssl - Win32 Release"
-
-"libaprutil - Win32 Release" :
- cd ".\..\..\srclib\apr-util"
- $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release"
- cd "..\..\modules\ssl"
-
-"libaprutil - Win32 ReleaseCLEAN" :
- cd ".\..\..\srclib\apr-util"
- $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Release" RECURSE=1 CLEAN
- cd "..\..\modules\ssl"
-
-!ELSEIF "$(CFG)" == "mod_ssl - Win32 Debug"
-
-"libaprutil - Win32 Debug" :
- cd ".\..\..\srclib\apr-util"
- $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug"
- cd "..\..\modules\ssl"
-
-"libaprutil - Win32 DebugCLEAN" :
- cd ".\..\..\srclib\apr-util"
- $(MAKE) /$(MAKEFLAGS) /F ".\libaprutil.mak" CFG="libaprutil - Win32 Debug" RECURSE=1 CLEAN
- cd "..\..\modules\ssl"
-
-!ELSEIF "$(CFG)" == "mod_ssl - Win32 Lexical"
-
-!ENDIF
-
-!IF "$(CFG)" == "mod_ssl - Win32 Release"
-
-"libhttpd - Win32 Release" :
- cd ".\..\.."
- $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release"
- cd ".\modules\ssl"
-
-"libhttpd - Win32 ReleaseCLEAN" :
- cd ".\..\.."
- $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Release" RECURSE=1 CLEAN
- cd ".\modules\ssl"
-
-!ELSEIF "$(CFG)" == "mod_ssl - Win32 Debug"
-
-"libhttpd - Win32 Debug" :
- cd ".\..\.."
- $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug"
- cd ".\modules\ssl"
-
-"libhttpd - Win32 DebugCLEAN" :
- cd ".\..\.."
- $(MAKE) /$(MAKEFLAGS) /F ".\libhttpd.mak" CFG="libhttpd - Win32 Debug" RECURSE=1 CLEAN
- cd ".\modules\ssl"
-
-!ELSEIF "$(CFG)" == "mod_ssl - Win32 Lexical"
-
-!ENDIF
-
-SOURCE=..\..\build\win32\httpd.rc
-
-!IF "$(CFG)" == "mod_ssl - Win32 Release"
-
-
-"$(INTDIR)\mod_ssl.res" : $(SOURCE) "$(INTDIR)"
- $(RSC) /l 0x409 /fo"$(INTDIR)\mod_ssl.res" /i "../../include" /i "../../srclib/apr/include" /i ".\..\..\build\win32" /d "NDEBUG" /d BIN_NAME="mod_ssl.so" /d LONG_NAME="proxy_ssl_module for Apache" $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "mod_ssl - Win32 Debug"
-
-
-"$(INTDIR)\mod_ssl.res" : $(SOURCE) "$(INTDIR)"
- $(RSC) /l 0x409 /fo"$(INTDIR)\mod_ssl.res" /i "../../include" /i "../../srclib/apr/include" /i ".\..\..\build\win32" /d "_DEBUG" /d BIN_NAME="mod_ssl.so" /d LONG_NAME="proxy_ssl_module for Apache" $(SOURCE)
-
-
-!ELSEIF "$(CFG)" == "mod_ssl - Win32 Lexical"
-
-
-"$(INTDIR)\mod_ssl.res" : $(SOURCE) "$(INTDIR)"
- $(RSC) /l 0x409 /fo"$(INTDIR)\mod_ssl.res" /i "../../include" /i "../../srclib/apr/include" /i ".\..\..\build\win32" /d "NDEBUG" /d BIN_NAME="mod_ssl.so" /d LONG_NAME="proxy_ssl_module for Apache" $(SOURCE)
-
-
-!ENDIF
-
-
-!ENDIF
-
diff --git a/modules/ssl/ssl_engine_config.c b/modules/ssl/ssl_engine_config.c
index 8d3b99d4..8b2d53ad 100644
--- a/modules/ssl/ssl_engine_config.c
+++ b/modules/ssl/ssl_engine_config.c
@@ -27,6 +27,8 @@
damned if you don't.''
-- Unknown */
#include "ssl_private.h"
+#include "util_mutex.h"
+#include "ap_provider.h"
/* _________________________________________________________________
**
@@ -57,15 +59,8 @@ SSLModConfigRec *ssl_config_global_create(server_rec *s)
/*
* initialize per-module configuration
*/
- mc->nSessionCacheMode = SSL_SCMODE_UNSET;
- mc->szSessionCacheDataFile = NULL;
- mc->nSessionCacheDataSize = 0;
- mc->pSessionCacheDataMM = NULL;
- mc->pSessionCacheDataRMM = NULL;
- mc->tSessionCacheDataTable = NULL;
- mc->nMutexMode = SSL_MUTEXMODE_UNSET;
- mc->nMutexMech = APR_LOCK_DEFAULT;
- mc->szMutexFile = NULL;
+ mc->sesscache_mode = SSL_SESS_CACHE_OFF;
+ mc->sesscache = NULL;
mc->pMutex = NULL;
mc->aRandSeed = apr_array_make(pool, 4,
sizeof(ssl_randseed_t));
@@ -75,6 +70,10 @@ SSLModConfigRec *ssl_config_global_create(server_rec *s)
#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
mc->szCryptoDevice = NULL;
#endif
+#ifdef HAVE_OCSP_STAPLING
+ mc->stapling_cache = NULL;
+ mc->stapling_mutex = NULL;
+#endif
memset(mc->pTmpKeys, 0, sizeof(mc->pTmpKeys));
@@ -110,22 +109,46 @@ static void modssl_ctx_init(modssl_ctx_t *mctx)
mctx->pks = NULL;
mctx->pkp = NULL;
+#ifdef HAVE_TLS_SESSION_TICKETS
+ mctx->ticket_key = NULL;
+#endif
+
mctx->protocol = SSL_PROTOCOL_ALL;
mctx->pphrase_dialog_type = SSL_PPTYPE_UNSET;
mctx->pphrase_dialog_path = NULL;
+ mctx->pkcs7 = NULL;
mctx->cert_chain = NULL;
mctx->crl_path = NULL;
mctx->crl_file = NULL;
- mctx->crl = NULL; /* set during module init */
+ mctx->crl_check_mode = SSL_CRLCHECK_UNSET;
mctx->auth.ca_cert_path = NULL;
mctx->auth.ca_cert_file = NULL;
mctx->auth.cipher_suite = NULL;
mctx->auth.verify_depth = UNSET;
mctx->auth.verify_mode = SSL_CVERIFY_UNSET;
+
+ mctx->ocsp_enabled = FALSE;
+ mctx->ocsp_force_default = FALSE;
+ mctx->ocsp_responder = NULL;
+ mctx->ocsp_resptime_skew = UNSET;
+ mctx->ocsp_resp_maxage = UNSET;
+ mctx->ocsp_responder_timeout = UNSET;
+
+#ifdef HAVE_OCSP_STAPLING
+ mctx->stapling_enabled = UNSET;
+ mctx->stapling_resptime_skew = UNSET;
+ mctx->stapling_resp_maxage = UNSET;
+ mctx->stapling_cache_timeout = UNSET;
+ mctx->stapling_return_errors = UNSET;
+ mctx->stapling_fake_trylater = UNSET;
+ mctx->stapling_errcache_timeout = UNSET;
+ mctx->stapling_responder_timeout = UNSET;
+ mctx->stapling_force_url = NULL;
+#endif
}
static void modssl_ctx_init_proxy(SSLSrvConfigRec *sc,
@@ -141,7 +164,9 @@ static void modssl_ctx_init_proxy(SSLSrvConfigRec *sc,
mctx->pkp->cert_file = NULL;
mctx->pkp->cert_path = NULL;
+ mctx->pkp->ca_cert_file = NULL;
mctx->pkp->certs = NULL;
+ mctx->pkp->ca_certs = NULL;
}
static void modssl_ctx_init_server(SSLSrvConfigRec *sc,
@@ -156,6 +181,10 @@ static void modssl_ctx_init_server(SSLSrvConfigRec *sc,
mctx->pks = apr_pcalloc(p, sizeof(*mctx->pks));
/* mctx->pks->... certs/keys are set during module init */
+
+#ifdef HAVE_TLS_SESSION_TICKETS
+ mctx->ticket_key = apr_pcalloc(p, sizeof(*mctx->ticket_key));
+#endif
}
static SSLSrvConfigRec *ssl_config_server_new(apr_pool_t *p)
@@ -217,12 +246,31 @@ static void modssl_ctx_cfg_merge(modssl_ctx_t *base,
cfgMerge(crl_path, NULL);
cfgMerge(crl_file, NULL);
+ cfgMerge(crl_check_mode, SSL_CRLCHECK_UNSET);
cfgMergeString(auth.ca_cert_path);
cfgMergeString(auth.ca_cert_file);
cfgMergeString(auth.cipher_suite);
cfgMergeInt(auth.verify_depth);
cfgMerge(auth.verify_mode, SSL_CVERIFY_UNSET);
+
+ cfgMergeBool(ocsp_enabled);
+ cfgMergeBool(ocsp_force_default);
+ cfgMerge(ocsp_responder, NULL);
+ cfgMergeInt(ocsp_resptime_skew);
+ cfgMergeInt(ocsp_resp_maxage);
+ cfgMergeInt(ocsp_responder_timeout);
+#ifdef HAVE_OCSP_STAPLING
+ cfgMergeBool(stapling_enabled);
+ cfgMergeInt(stapling_resptime_skew);
+ cfgMergeInt(stapling_resp_maxage);
+ cfgMergeInt(stapling_cache_timeout);
+ cfgMergeBool(stapling_return_errors);
+ cfgMergeBool(stapling_fake_trylater);
+ cfgMergeInt(stapling_errcache_timeout);
+ cfgMergeInt(stapling_responder_timeout);
+ cfgMerge(stapling_force_url, NULL);
+#endif
}
static void modssl_ctx_cfg_merge_proxy(modssl_ctx_t *base,
@@ -233,6 +281,7 @@ static void modssl_ctx_cfg_merge_proxy(modssl_ctx_t *base,
cfgMergeString(pkp->cert_file);
cfgMergeString(pkp->cert_path);
+ cfgMergeString(pkp->ca_cert_file);
}
static void modssl_ctx_cfg_merge_server(modssl_ctx_t *base,
@@ -250,6 +299,10 @@ static void modssl_ctx_cfg_merge_server(modssl_ctx_t *base,
cfgMergeString(pks->ca_name_path);
cfgMergeString(pks->ca_name_file);
+
+#ifdef HAVE_TLS_SESSION_TICKETS
+ cfgMergeString(ticket_key->file_path);
+#endif
}
/*
@@ -352,99 +405,6 @@ void *ssl_config_perdir_merge(apr_pool_t *p, void *basev, void *addv)
* Configuration functions for particular directives
*/
-const char *ssl_cmd_SSLMutex(cmd_parms *cmd,
- void *dcfg,
- const char *arg_)
-{
- const char *err;
- SSLModConfigRec *mc = myModConfig(cmd->server);
- /* Split arg_ into meth and file */
- char *meth = apr_pstrdup(cmd->temp_pool, arg_);
- char *file = strchr(meth, ':');
- if (file) {
- *(file++) = '\0';
- if (!*file) {
- file = NULL;
- }
- }
-
- if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
- return err;
- }
-
- if (ssl_config_global_isfixed(mc)) {
- return NULL;
- }
- if (!strcasecmp(meth, "none") || !strcasecmp(meth, "no")) {
- mc->nMutexMode = SSL_MUTEXMODE_NONE;
- return NULL;
- }
-
- /* APR determines temporary filename unless overridden below,
- * we presume file indicates an szMutexFile is a file path
- * unless the method sets szMutexFile=file and NULLs file
- */
- mc->nMutexMode = SSL_MUTEXMODE_USED;
- mc->szMutexFile = NULL;
-
- /* NOTE: previously, 'yes' implied 'sem' */
- if (!strcasecmp(meth, "default") || !strcasecmp(meth, "yes")) {
- mc->nMutexMech = APR_LOCK_DEFAULT;
- }
-#if APR_HAS_FCNTL_SERIALIZE
- else if ((!strcasecmp(meth, "fcntl") || !strcasecmp(meth, "file")) && file) {
- mc->nMutexMech = APR_LOCK_FCNTL;
- }
-#endif
-#if APR_HAS_FLOCK_SERIALIZE
- else if ((!strcasecmp(meth, "flock") || !strcasecmp(meth, "file")) && file) {
- mc->nMutexMech = APR_LOCK_FLOCK;
- }
-#endif
-#if APR_HAS_POSIXSEM_SERIALIZE
- else if (!strcasecmp(meth, "posixsem") || !strcasecmp(meth, "sem")) {
- mc->nMutexMech = APR_LOCK_POSIXSEM;
- /* Posix/SysV semaphores aren't file based, use the literal name
- * if provided and fall back on APR's default if not. Today, APR
- * will ignore it, but once supported it has an absurdly short limit.
- */
- if (file) {
- mc->szMutexFile = apr_pstrdup(cmd->server->process->pool, file);
-
- file = NULL;
- }
- }
-#endif
-#if APR_HAS_SYSVSEM_SERIALIZE && !defined(PERCHILD_MPM)
- else if (!strcasecmp(meth, "sysvsem") || !strcasecmp(meth, "sem")) {
- mc->nMutexMech = APR_LOCK_SYSVSEM;
- }
-#endif
-#if APR_HAS_PROC_PTHREAD_SERIALIZE
- else if (!strcasecmp(meth, "pthread")) {
- mc->nMutexMech = APR_LOCK_PROC_PTHREAD;
- }
-#endif
- else {
- return apr_pstrcat(cmd->pool, "Invalid SSLMutex argument ", arg_,
- " (", ssl_valid_ssl_mutex_string, ")", NULL);
- }
-
- /* Unless the method above assumed responsibility for setting up
- * mc->szMutexFile and NULLing out file, presume it is a file we
- * are looking to use
- */
- if (file) {
- mc->szMutexFile = ap_server_root_relative(cmd->server->process->pool, file);
- if (!mc->szMutexFile) {
- return apr_pstrcat(cmd->pool, "Invalid SSLMutex ", meth,
- ": filepath ", file, NULL);
- }
- }
-
- return NULL;
-}
-
const char *ssl_cmd_SSLPassPhraseDialog(cmd_parms *cmd,
void *dcfg,
const char *arg)
@@ -517,12 +477,11 @@ const char *ssl_cmd_SSLCryptoDevice(cmd_parms *cmd,
"'builtin' (none)";
e = ENGINE_get_first();
while (e) {
- ENGINE *en;
err = apr_pstrcat(cmd->pool, err, ", '", ENGINE_get_id(e),
"' (", ENGINE_get_name(e), ")", NULL);
- en = ENGINE_get_next(e);
- ENGINE_free(e);
- e = en;
+ /* Iterate; this call implicitly decrements the refcount
+ * on the 'old' e, per the docs in engine.h. */
+ e = ENGINE_get_next(e);
}
return err;
}
@@ -573,12 +532,8 @@ const char *ssl_cmd_SSLRandomSeed(cmd_parms *cmd,
seed->cpPath = ap_server_root_relative(mc->pPool, arg2+5);
}
else if ((arg2len > 4) && strEQn(arg2, "egd:", 4)) {
-#ifdef HAVE_SSL_RAND_EGD
seed->nSrc = SSL_RSSRC_EGD;
seed->cpPath = ap_server_root_relative(mc->pPool, arg2+4);
-#else
- return "egd not supported with this SSL toolkit";
-#endif
}
else if (strcEQ(arg2, "builtin")) {
seed->nSrc = SSL_RSSRC_BUILTIN;
@@ -835,23 +790,42 @@ const char *ssl_cmd_SSLCertificateChainFile(cmd_parms *cmd,
return NULL;
}
-#define NO_PER_DIR_SSL_CA \
- "Your ssl library does not have support for per-directory CA"
+const char *ssl_cmd_SSLPKCS7CertificateFile(cmd_parms *cmd,
+ void *dcfg,
+ const char *arg)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ const char *err;
-#ifdef HAVE_SSL_SET_CERT_STORE
-# define MODSSL_HAVE_SSL_SET_CERT_STORE 1
-#else
-# define MODSSL_HAVE_SSL_SET_CERT_STORE 0
+ if ((err = ssl_cmd_check_file(cmd, &arg))) {
+ return err;
+ }
+
+ sc->server->pkcs7 = arg;
+
+ return NULL;
+}
+
+#ifdef HAVE_TLS_SESSION_TICKETS
+const char *ssl_cmd_SSLSessionTicketKeyFile(cmd_parms *cmd,
+ void *dcfg,
+ const char *arg)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ const char *err;
+
+ if ((err = ssl_cmd_check_file(cmd, &arg))) {
+ return err;
+ }
+
+ sc->server->ticket_key->file_path = arg;
+
+ return NULL;
+}
#endif
-#define MODSSL_SET_CA(f) \
- if (cmd->path) \
- if (MODSSL_HAVE_SSL_SET_CERT_STORE) \
- dc->f = arg; \
- else \
- return NO_PER_DIR_SSL_CA; \
- else \
- sc->f = arg \
+#define NO_PER_DIR_SSL_CA \
+ "Your SSL library does not have support for per-directory CA"
const char *ssl_cmd_SSLCACertificatePath(cmd_parms *cmd,
void *dcfg,
@@ -865,6 +839,10 @@ const char *ssl_cmd_SSLCACertificatePath(cmd_parms *cmd,
return err;
}
+ if (cmd->path) {
+ return NO_PER_DIR_SSL_CA;
+ }
+
/* XXX: bring back per-dir */
sc->server->auth.ca_cert_path = arg;
@@ -883,6 +861,10 @@ const char *ssl_cmd_SSLCACertificateFile(cmd_parms *cmd,
return err;
}
+ if (cmd->path) {
+ return NO_PER_DIR_SSL_CA;
+ }
+
/* XXX: bring back per-dir */
sc->server->auth.ca_cert_file = arg;
@@ -951,6 +933,37 @@ const char *ssl_cmd_SSLCARevocationFile(cmd_parms *cmd,
return NULL;
}
+static const char *ssl_cmd_crlcheck_parse(cmd_parms *parms,
+ const char *arg,
+ ssl_crlcheck_t *mode)
+{
+ if (strcEQ(arg, "none")) {
+ *mode = SSL_CRLCHECK_NONE;
+ }
+ else if (strcEQ(arg, "leaf")) {
+ *mode = SSL_CRLCHECK_LEAF;
+ }
+ else if (strcEQ(arg, "chain")) {
+ *mode = SSL_CRLCHECK_CHAIN;
+ }
+ else {
+ return apr_pstrcat(parms->temp_pool, parms->cmd->name,
+ ": Invalid argument '", arg, "'",
+ NULL);
+ }
+
+ return NULL;
+}
+
+const char *ssl_cmd_SSLCARevocationCheck(cmd_parms *cmd,
+ void *dcfg,
+ const char *arg)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+
+ return ssl_cmd_crlcheck_parse(cmd, arg, &sc->server->crl_check_mode);
+}
+
static const char *ssl_cmd_verify_parse(cmd_parms *parms,
const char *arg,
ssl_verify_t *id)
@@ -1035,103 +1048,77 @@ const char *ssl_cmd_SSLVerifyDepth(cmd_parms *cmd,
return NULL;
}
-#define MODSSL_NO_SHARED_MEMORY_ERROR \
- "SSLSessionCache: shared memory cache not useable on this platform"
-
const char *ssl_cmd_SSLSessionCache(cmd_parms *cmd,
void *dcfg,
const char *arg)
{
SSLModConfigRec *mc = myModConfig(cmd->server);
- const char *err, *colon;
- char *cp, *cp2;
- int arglen = strlen(arg);
+ const char *err, *sep, *name;
+ long enabled_flags;
if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
return err;
}
- if (ssl_config_global_isfixed(mc)) {
- return NULL;
- }
+ /* The OpenSSL session cache mode must have both the flags
+ * SSL_SESS_CACHE_SERVER and SSL_SESS_CACHE_NO_INTERNAL set if a
+ * session cache is configured; NO_INTERNAL prevents the
+ * OpenSSL-internal session cache being used in addition to the
+ * "external" (mod_ssl-provided) cache, which otherwise causes
+ * additional memory consumption. */
+ enabled_flags = SSL_SESS_CACHE_SERVER | SSL_SESS_CACHE_NO_INTERNAL;
if (strcEQ(arg, "none")) {
- mc->nSessionCacheMode = SSL_SCMODE_NONE;
- mc->szSessionCacheDataFile = NULL;
+ /* Nothing to do; session cache will be off. */
}
else if (strcEQ(arg, "nonenotnull")) {
- mc->nSessionCacheMode = SSL_SCMODE_NONE_NOT_NULL;
- mc->szSessionCacheDataFile = NULL;
- }
- else if ((arglen > 4) && strcEQn(arg, "dbm:", 4)) {
- mc->nSessionCacheMode = SSL_SCMODE_DBM;
- mc->szSessionCacheDataFile = ap_server_root_relative(mc->pPool, arg+4);
- if (!mc->szSessionCacheDataFile) {
- return apr_psprintf(cmd->pool,
- "SSLSessionCache: Invalid cache file path %s",
- arg+4);
- }
+ /* ### Having a separate mode for this seems logically
+ * unnecessary; the stated purpose of sending non-empty
+ * session IDs would be better fixed in OpenSSL or simply
+ * doing it by default if "none" is used. */
+ mc->sesscache_mode = enabled_flags;
}
- else if (((arglen > 4) && strcEQn(arg, "shm:", 4)) ||
- ((arglen > 6) && strcEQn(arg, "shmht:", 6)) ||
- ((arglen > 6) && strcEQn(arg, "shmcb:", 6))) {
-#if !APR_HAS_SHARED_MEMORY
- return MODSSL_NO_SHARED_MEMORY_ERROR;
-#endif
- mc->nSessionCacheMode = SSL_SCMODE_SHMCB;
- colon = ap_strchr_c(arg, ':');
- mc->szSessionCacheDataFile =
- ap_server_root_relative(mc->pPool, colon+1);
- if (!mc->szSessionCacheDataFile) {
- return apr_psprintf(cmd->pool,
- "SSLSessionCache: Invalid cache file path %s",
- colon+1);
+ else {
+ /* Argument is of form 'name:args' or just 'name'. */
+ sep = ap_strchr_c(arg, ':');
+ if (sep) {
+ name = apr_pstrmemdup(cmd->pool, arg, sep - arg);
+ sep++;
+ }
+ else {
+ name = arg;
}
- mc->tSessionCacheDataTable = NULL;
- mc->nSessionCacheDataSize = 1024*512; /* 512KB */
-
- if ((cp = strchr(mc->szSessionCacheDataFile, '('))) {
- *cp++ = NUL;
-
- if (!(cp2 = strchr(cp, ')'))) {
- return "SSLSessionCache: Invalid argument: "
- "no closing parenthesis";
- }
-
- *cp2 = NUL;
-
- mc->nSessionCacheDataSize = atoi(cp);
-
- if (mc->nSessionCacheDataSize < 8192) {
- return "SSLSessionCache: Invalid argument: "
- "size has to be >= 8192 bytes";
-
- }
-
- if (mc->nSessionCacheDataSize >= APR_SHM_MAXSIZE) {
- return apr_psprintf(cmd->pool,
- "SSLSessionCache: Invalid argument: "
- "size has to be < %d bytes on this "
- "platform", APR_SHM_MAXSIZE);
- }
+ /* Find the provider of given name. */
+ mc->sesscache = ap_lookup_provider(AP_SOCACHE_PROVIDER_GROUP,
+ name,
+ AP_SOCACHE_PROVIDER_VERSION);
+ if (mc->sesscache) {
+ /* Cache found; create it, passing anything beyond the colon. */
+ mc->sesscache_mode = enabled_flags;
+ err = mc->sesscache->create(&mc->sesscache_context, sep,
+ cmd->temp_pool, cmd->pool);
}
- }
- else if ((arglen > 3) && strcEQn(arg, "dc:", 3)) {
-#ifdef HAVE_DISTCACHE
- mc->nSessionCacheMode = SSL_SCMODE_DC;
- mc->szSessionCacheDataFile = apr_pstrdup(mc->pPool, arg+3);
- if (!mc->szSessionCacheDataFile) {
- return apr_pstrcat(cmd->pool,
- "SSLSessionCache: Invalid cache file path: ",
- arg+3, NULL);
+ else {
+ apr_array_header_t *name_list;
+ const char *all_names;
+
+ /* Build a comma-separated list of all registered provider
+ * names: */
+ name_list = ap_list_provider_names(cmd->pool,
+ AP_SOCACHE_PROVIDER_GROUP,
+ AP_SOCACHE_PROVIDER_VERSION);
+ all_names = apr_array_pstrcat(cmd->pool, name_list, ',');
+
+ err = apr_psprintf(cmd->pool, "'%s' session cache not supported "
+ "(known names: %s). Maybe you need to load the "
+ "appropriate socache module (mod_socache_%s?).",
+ name, all_names, name);
}
-#else
- return "SSLSessionCache: distcache support disabled";
-#endif
}
- else {
- return "SSLSessionCache: Invalid argument";
+
+ if (err) {
+ return apr_psprintf(cmd->pool, "SSLSessionCache: %s", err);
}
return NULL;
@@ -1162,7 +1149,7 @@ const char *ssl_cmd_SSLOptions(cmd_parms *cmd,
char action, *w;
while (*arg) {
- w = ap_getword_conf(cmd->pool, &arg);
+ w = ap_getword_conf(cmd->temp_pool, &arg);
action = NUL;
if ((*w == '+') || (*w == '-')) {
@@ -1188,6 +1175,9 @@ const char *ssl_cmd_SSLOptions(cmd_parms *cmd,
else if (strcEQ(w, "OptRenegotiate")) {
opt = SSL_OPT_OPTRENEGOTIATE;
}
+ else if (strcEQ(w, "LegacyDNStringFormat")) {
+ opt = SSL_OPT_LEGACYDNFORMAT;
+ }
else {
return apr_pstrcat(cmd->pool,
"SSLOptions: Illegal option '", w, "'",
@@ -1228,17 +1218,22 @@ const char *ssl_cmd_SSLRequire(cmd_parms *cmd,
const char *arg)
{
SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
- ssl_expr *expr;
+ ap_expr_info_t *info = apr_pcalloc(cmd->pool, sizeof(ap_expr_info_t));
ssl_require_t *require;
+ const char *errstring;
- if (!(expr = ssl_expr_comp(cmd->pool, (char *)arg))) {
- return apr_pstrcat(cmd->pool, "SSLRequire: ",
- ssl_expr_get_error(), NULL);
+ info->flags = AP_EXPR_FLAG_SSL_EXPR_COMPAT;
+ info->filename = cmd->directive->filename;
+ info->line_number = cmd->directive->line_num;
+ info->module_index = APLOG_MODULE_INDEX;
+ errstring = ap_expr_parse(cmd->pool, cmd->temp_pool, info, arg, NULL);
+ if (errstring) {
+ return apr_pstrcat(cmd->pool, "SSLRequire: ", errstring, NULL);
}
require = apr_array_push(dc->aRequirement);
require->cpExpr = apr_pstrdup(cmd->pool, arg);
- require->mpExpr = expr;
+ require->mpExpr = info;
return NULL;
}
@@ -1246,12 +1241,14 @@ const char *ssl_cmd_SSLRequire(cmd_parms *cmd,
const char *ssl_cmd_SSLRenegBufferSize(cmd_parms *cmd, void *dcfg, const char *arg)
{
SSLDirConfigRec *dc = dcfg;
-
- dc->nRenegBufferSize = atoi(arg);
- if (dc->nRenegBufferSize < 0) {
+ int val;
+
+ val = atoi(arg);
+ if (val < 0) {
return apr_pstrcat(cmd->pool, "Invalid size for SSLRenegBufferSize: ",
arg, NULL);
}
+ dc->nRenegBufferSize = val;
return NULL;
}
@@ -1273,12 +1270,12 @@ static const char *ssl_cmd_protocol_parse(cmd_parms *parms,
}
if (strcEQ(w, "SSLv2")) {
-#ifdef OPENSSL_NO_SSL2
- if (action != '-') {
- return "SSLv2 not supported by this version of OpenSSL";
+ if (action == '-') {
+ continue;
+ }
+ else {
+ return "SSLProtocol: SSLv2 is no longer supported";
}
-#endif
- thisopt = SSL_PROTOCOL_SSLV2;
}
else if (strcEQ(w, "SSLv3")) {
thisopt = SSL_PROTOCOL_SSLV3;
@@ -1446,6 +1443,15 @@ const char *ssl_cmd_SSLProxyCARevocationFile(cmd_parms *cmd,
return NULL;
}
+const char *ssl_cmd_SSLProxyCARevocationCheck(cmd_parms *cmd,
+ void *dcfg,
+ const char *arg)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+
+ return ssl_cmd_crlcheck_parse(cmd, arg, &sc->proxy->crl_check_mode);
+}
+
const char *ssl_cmd_SSLProxyMachineCertificateFile(cmd_parms *cmd,
void *dcfg,
const char *arg)
@@ -1478,6 +1484,21 @@ const char *ssl_cmd_SSLProxyMachineCertificatePath(cmd_parms *cmd,
return NULL;
}
+const char *ssl_cmd_SSLProxyMachineCertificateChainFile(cmd_parms *cmd,
+ void *dcfg,
+ const char *arg)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ const char *err;
+
+ if ((err = ssl_cmd_check_file(cmd, &arg))) {
+ return err;
+ }
+
+ sc->proxy->pkp->ca_cert_file = arg;
+
+ return NULL;
+}
const char *ssl_cmd_SSLUserName(cmd_parms *cmd, void *dcfg,
const char *arg)
@@ -1487,6 +1508,70 @@ const char *ssl_cmd_SSLUserName(cmd_parms *cmd, void *dcfg,
return NULL;
}
+const char *ssl_cmd_SSLOCSPEnable(cmd_parms *cmd, void *dcfg, int flag)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+
+ sc->server->ocsp_enabled = flag ? TRUE : FALSE;
+
+#ifdef OPENSSL_NO_OCSP
+ if (flag) {
+ return "OCSP support disabled in SSL library; cannot enable "
+ "OCSP validation";
+ }
+#endif
+
+ return NULL;
+}
+
+const char *ssl_cmd_SSLOCSPOverrideResponder(cmd_parms *cmd, void *dcfg, int flag)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+
+ sc->server->ocsp_force_default = flag ? TRUE : FALSE;
+
+ return NULL;
+}
+
+const char *ssl_cmd_SSLOCSPDefaultResponder(cmd_parms *cmd, void *dcfg, const char *arg)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+
+ sc->server->ocsp_responder = arg;
+
+ return NULL;
+}
+
+const char *ssl_cmd_SSLOCSPResponseTimeSkew(cmd_parms *cmd, void *dcfg, const char *arg)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ sc->server->ocsp_resptime_skew = atoi(arg);
+ if (sc->server->ocsp_resptime_skew < 0) {
+ return "SSLOCSPResponseTimeSkew: invalid argument";
+ }
+ return NULL;
+}
+
+const char *ssl_cmd_SSLOCSPResponseMaxAge(cmd_parms *cmd, void *dcfg, const char *arg)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ sc->server->ocsp_resp_maxage = atoi(arg);
+ if (sc->server->ocsp_resp_maxage < 0) {
+ return "SSLOCSPResponseMaxAge: invalid argument";
+ }
+ return NULL;
+}
+
+const char *ssl_cmd_SSLOCSPResponderTimeout(cmd_parms *cmd, void *dcfg, const char *arg)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ sc->server->ocsp_responder_timeout = apr_time_from_sec(atoi(arg));
+ if (sc->server->ocsp_responder_timeout < 0) {
+ return "SSLOCSPResponderTimeout: invalid argument";
+ }
+ return NULL;
+}
+
const char *ssl_cmd_SSLProxyCheckPeerExpire(cmd_parms *cmd, void *dcfg, int flag)
{
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
@@ -1520,11 +1605,160 @@ const char *ssl_cmd_SSLStrictSNIVHostCheck(cmd_parms *cmd, void *dcfg, int flag
#endif
}
+#ifdef HAVE_OCSP_STAPLING
+
+const char *ssl_cmd_SSLStaplingCache(cmd_parms *cmd,
+ void *dcfg,
+ const char *arg)
+{
+ SSLModConfigRec *mc = myModConfig(cmd->server);
+ const char *err, *sep, *name;
+
+ if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
+ return err;
+ }
+
+ /* Argument is of form 'name:args' or just 'name'. */
+ sep = ap_strchr_c(arg, ':');
+ if (sep) {
+ name = apr_pstrmemdup(cmd->pool, arg, sep - arg);
+ sep++;
+ }
+ else {
+ name = arg;
+ }
+
+ /* Find the provider of given name. */
+ mc->stapling_cache = ap_lookup_provider(AP_SOCACHE_PROVIDER_GROUP,
+ name,
+ AP_SOCACHE_PROVIDER_VERSION);
+ if (mc->stapling_cache) {
+ /* Cache found; create it, passing anything beyond the colon. */
+ err = mc->stapling_cache->create(&mc->stapling_cache_context,
+ sep, cmd->temp_pool,
+ cmd->pool);
+ }
+ else {
+ apr_array_header_t *name_list;
+ const char *all_names;
+
+ /* Build a comma-separated list of all registered provider
+ * names: */
+ name_list = ap_list_provider_names(cmd->pool,
+ AP_SOCACHE_PROVIDER_GROUP,
+ AP_SOCACHE_PROVIDER_VERSION);
+ all_names = apr_array_pstrcat(cmd->pool, name_list, ',');
+
+ err = apr_psprintf(cmd->pool, "'%s' stapling cache not supported "
+ "(known names: %s) Maybe you need to load the "
+ "appropriate socache module (mod_socache_%s?)",
+ name, all_names, name);
+ }
+
+ if (err) {
+ return apr_psprintf(cmd->pool, "SSLStaplingCache: %s", err);
+ }
+
+ return NULL;
+}
+
+const char *ssl_cmd_SSLUseStapling(cmd_parms *cmd, void *dcfg, int flag)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ sc->server->stapling_enabled = flag ? TRUE : FALSE;
+ return NULL;
+}
+
+const char *ssl_cmd_SSLStaplingResponseTimeSkew(cmd_parms *cmd, void *dcfg,
+ const char *arg)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ sc->server->stapling_resptime_skew = atoi(arg);
+ if (sc->server->stapling_resptime_skew < 0) {
+ return "SSLStaplingResponseTimeSkew: invalid argument";
+ }
+ return NULL;
+}
+
+const char *ssl_cmd_SSLStaplingResponseMaxAge(cmd_parms *cmd, void *dcfg,
+ const char *arg)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ sc->server->stapling_resp_maxage = atoi(arg);
+ if (sc->server->stapling_resp_maxage < 0) {
+ return "SSLStaplingResponseMaxAge: invalid argument";
+ }
+ return NULL;
+}
+
+const char *ssl_cmd_SSLStaplingStandardCacheTimeout(cmd_parms *cmd, void *dcfg,
+ const char *arg)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ sc->server->stapling_cache_timeout = atoi(arg);
+ if (sc->server->stapling_cache_timeout < 0) {
+ return "SSLStaplingStandardCacheTimeout: invalid argument";
+ }
+ return NULL;
+}
+
+const char *ssl_cmd_SSLStaplingErrorCacheTimeout(cmd_parms *cmd, void *dcfg,
+ const char *arg)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ sc->server->stapling_errcache_timeout = atoi(arg);
+ if (sc->server->stapling_errcache_timeout < 0) {
+ return "SSLStaplingErrorCacheTimeout: invalid argument";
+ }
+ return NULL;
+}
+
+const char *ssl_cmd_SSLStaplingReturnResponderErrors(cmd_parms *cmd,
+ void *dcfg, int flag)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ sc->server->stapling_return_errors = flag ? TRUE : FALSE;
+ return NULL;
+}
+
+const char *ssl_cmd_SSLStaplingFakeTryLater(cmd_parms *cmd,
+ void *dcfg, int flag)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ sc->server->stapling_fake_trylater = flag ? TRUE : FALSE;
+ return NULL;
+}
+
+const char *ssl_cmd_SSLStaplingResponderTimeout(cmd_parms *cmd, void *dcfg,
+ const char *arg)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ sc->server->stapling_responder_timeout = atoi(arg);
+ sc->server->stapling_responder_timeout *= APR_USEC_PER_SEC;
+ if (sc->server->stapling_responder_timeout < 0) {
+ return "SSLStaplingResponderTimeout: invalid argument";
+ }
+ return NULL;
+}
+
+const char *ssl_cmd_SSLStaplingForceURL(cmd_parms *cmd, void *dcfg,
+ const char *arg)
+{
+ SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
+ sc->server->stapling_force_url = arg;
+ return NULL;
+}
+
+#endif /* HAVE_OCSP_STAPLING */
+
void ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s)
{
+ apr_file_t *out = NULL;
if (!ap_exists_config_define("DUMP_CERTS")) {
return;
}
+ apr_file_open_stdout(&out, pconf);
+ apr_file_printf(out, "Server certificates:\n");
/* Dump the filenames of all configured server certificates to
* stdout. */
@@ -1536,7 +1770,7 @@ void ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s)
int i;
for (i = 0; (i < SSL_AIDX_MAX) && pks->cert_files[i]; i++) {
- printf("%s\n", pks->cert_files[i]);
+ apr_file_printf(out, " %s\n", pks->cert_files[i]);
}
}
diff --git a/modules/ssl/ssl_engine_dh.c b/modules/ssl/ssl_engine_dh.c
index 91d2df47..0cc74555 100644
--- a/modules/ssl/ssl_engine_dh.c
+++ b/modules/ssl/ssl_engine_dh.c
@@ -69,8 +69,20 @@ static unsigned char dh512_g[] = {
static DH *get_dh512(void)
{
- return modssl_dh_configure(dh512_p, sizeof(dh512_p),
- dh512_g, sizeof(dh512_g));
+ DH *dh;
+
+ if (!(dh = DH_new())) {
+ return NULL;
+ }
+
+ dh->p = BN_bin2bn(dh512_p, sizeof(dh512_p), NULL);
+ dh->g = BN_bin2bn(dh512_g, sizeof(dh512_g), NULL);
+ if (!(dh->p && dh->g)) {
+ DH_free(dh);
+ return NULL;
+ }
+
+ return dh;
}
static unsigned char dh1024_p[] = {
@@ -92,8 +104,20 @@ static unsigned char dh1024_g[] = {
static DH *get_dh1024(void)
{
- return modssl_dh_configure(dh1024_p, sizeof(dh1024_p),
- dh1024_g, sizeof(dh1024_g));
+ DH *dh;
+
+ if (!(dh = DH_new())) {
+ return NULL;
+ }
+
+ dh->p = BN_bin2bn(dh1024_p, sizeof(dh1024_p), NULL);
+ dh->g = BN_bin2bn(dh1024_g, sizeof(dh1024_g), NULL);
+ if (!(dh->p && dh->g)) {
+ DH_free(dh);
+ return NULL;
+ }
+
+ return dh;
}
/* ----END GENERATED SECTION---------- */
@@ -118,11 +142,7 @@ DH *ssl_dh_GetParamFromFile(char *file)
if ((bio = BIO_new_file(file, "r")) == NULL)
return NULL;
-#if SSL_LIBRARY_VERSION < 0x00904000
- dh = PEM_read_bio_DHparams(bio, NULL, NULL);
-#else
dh = PEM_read_bio_DHparams(bio, NULL, NULL, NULL);
-#endif
BIO_free(bio);
return (dh);
}
@@ -175,18 +195,32 @@ close(FP);
$dhinfo =~ s|^|** |mg;
$dhinfo = "\n\/\*\n$dhinfo\*\/\n\n";
+my $indent_args = "-i4 -npsl -di0 -br -nce -d0 -cli0 -npcs -nfc1";
+
# generate C source from DH params
my $dhsource = '';
-open(FP, "openssl dh -noout -C -in dh512.pem | indent | expand |") || die;
+open(FP, "openssl dh -noout -C -in dh512.pem | indent $indent_args | expand |") || die;
$dhsource .= $_ while (<FP>);
close(FP);
-open(FP, "openssl dh -noout -C -in dh1024.pem | indent | expand |") || die;
+open(FP, "openssl dh -noout -C -in dh1024.pem | indent $indent_args | expand |") || die;
$dhsource .= $_ while (<FP>);
close(FP);
$dhsource =~ s|(DH\s+\*get_dh)(\d+)[^}]*\n}|static $1$2(void)
{
- return modssl_dh_configure(dh$2_p, sizeof(dh$2_p),
- dh$2_g, sizeof(dh$2_g));
+ DH *dh;
+
+ if (!(dh = DH_new())) {
+ return NULL;
+ }
+
+ dh->p = BN_bin2bn(dh$2_p, sizeof(dh$2_p), NULL);
+ dh->g = BN_bin2bn(dh$2_g, sizeof(dh$2_g), NULL);
+ if (!(dh->p && dh->g)) {
+ DH_free(dh);
+ return NULL;
+ }
+
+ return dh;
}
|sg;
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
index 34535410..dc4269d8 100644
--- a/modules/ssl/ssl_engine_init.c
+++ b/modules/ssl/ssl_engine_init.c
@@ -27,6 +27,7 @@
see Recursive.''
-- Unknown */
#include "ssl_private.h"
+#include "mpm_common.h"
/* _________________________________________________________________
**
@@ -40,13 +41,12 @@ static void ssl_add_version_components(apr_pool_t *p,
{
char *modver = ssl_var_lookup(p, s, NULL, NULL, "SSL_VERSION_INTERFACE");
char *libver = ssl_var_lookup(p, s, NULL, NULL, "SSL_VERSION_LIBRARY");
- char *incver = ssl_var_lookup(p, s, NULL, NULL,
+ char *incver = ssl_var_lookup(p, s, NULL, NULL,
"SSL_VERSION_LIBRARY_INTERFACE");
- ap_add_version_component(p, modver);
ap_add_version_component(p, libver);
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01876)
"%s compiled against Server: %s, Library: %s",
modver, AP_SERVER_BASEVERSION, incver);
}
@@ -83,23 +83,42 @@ static int ssl_tmp_key_init_rsa(server_rec *s,
if (FIPS_mode() && bits < 1024) {
mc->pTmpKeys[idx] = NULL;
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01877)
"Init: Skipping generating temporary "
"%d bit RSA private key in FIPS mode", bits);
return OK;
}
#endif
-
+#ifdef HAVE_GENERATE_EX
+ {
+ RSA *tkey;
+ BIGNUM *bn_f4;
+ if (!(tkey = RSA_new())
+ || !(bn_f4 = BN_new())
+ || !BN_set_word(bn_f4, RSA_F4)
+ || !RSA_generate_key_ex(tkey, bits, bn_f4, NULL))
+ {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01878)
+ "Init: Failed to generate temporary "
+ "%d bit RSA private key", bits);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s);
+ return !OK;
+ }
+ BN_free(bn_f4);
+ mc->pTmpKeys[idx] = tkey;
+ }
+#else
if (!(mc->pTmpKeys[idx] =
RSA_generate_key(bits, RSA_F4, NULL, NULL)))
{
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01879)
"Init: Failed to generate temporary "
"%d bit RSA private key", bits);
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s);
return !OK;
}
+#endif
return OK;
}
@@ -113,7 +132,7 @@ static int ssl_tmp_key_init_dh(server_rec *s,
if (FIPS_mode() && bits < 1024) {
mc->pTmpKeys[idx] = NULL;
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01880)
"Init: Skipping generating temporary "
"%d bit DH parameters in FIPS mode", bits);
return OK;
@@ -124,7 +143,7 @@ static int ssl_tmp_key_init_dh(server_rec *s,
if (!(mc->pTmpKeys[idx] =
ssl_dh_GetTmpParam(bits)))
{
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01881)
"Init: Failed to generate temporary "
"%d bit DH parameters", bits);
return !OK;
@@ -141,7 +160,7 @@ static int ssl_tmp_key_init_dh(server_rec *s,
static int ssl_tmp_keys_init(server_rec *s)
{
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s,
"Init: Generating temporary RSA private keys (512/1024 bits)");
if (MODSSL_TMP_KEY_INIT_RSA(s, 512) ||
@@ -149,7 +168,7 @@ static int ssl_tmp_keys_init(server_rec *s)
return !OK;
}
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s,
"Init: Generating temporary DH parameters (512/1024 bits)");
if (MODSSL_TMP_KEY_INIT_DH(s, 512) ||
@@ -171,6 +190,14 @@ int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
SSLSrvConfigRec *sc;
server_rec *s;
+ if (SSLeay() < SSL_LIBRARY_VERSION) {
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, base_server, APLOGNO(01882)
+ "Init: this version of mod_ssl was compiled against "
+ "a newer library (%s, version currently loaded is %s)"
+ " - may result in undefined or erroneous behavior",
+ SSL_LIBRARY_TEXT, SSLeay_version(SSLEAY_VERSION));
+ }
+
/* We initialize mc->pid per-process in the child init,
* but it should be initialized for startup before we
* call ssl_rand_seed() below.
@@ -178,7 +205,7 @@ int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
mc->pid = getpid();
/*
- * Let us cleanup on restarts and exists
+ * Let us cleanup on restarts and exits
*/
apr_pool_cleanup_register(p, base_server,
ssl_init_ModuleKill,
@@ -229,7 +256,7 @@ int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
sc->session_cache_timeout = SSL_SESSION_CACHE_TIMEOUT;
}
- if (sc->server->pphrase_dialog_type == SSL_PPTYPE_UNSET) {
+ if (sc->server && sc->server->pphrase_dialog_type == SSL_PPTYPE_UNSET) {
sc->server->pphrase_dialog_type = SSL_PPTYPE_BUILTIN;
}
@@ -251,7 +278,7 @@ int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
ssl_init_Engine(base_server, p);
#endif
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01883)
"Init: Initialized %s library", SSL_LIBRARY_NAME);
/*
@@ -265,18 +292,18 @@ int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
if(sc->fips) {
if (!FIPS_mode()) {
if (FIPS_mode_set(1)) {
- ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, APLOGNO(01884)
"Operating in SSL FIPS mode");
}
else {
- ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, "FIPS mode failed");
- ssl_log_ssl_error(APLOG_MARK, APLOG_EMERG, s);
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01885) "FIPS mode failed");
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
ssl_die();
}
}
}
else {
- ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s, APLOGNO(01886)
"SSL FIPS mode disabled");
}
#endif
@@ -299,6 +326,9 @@ int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
if (!ssl_mutex_init(base_server, p)) {
return HTTP_INTERNAL_SERVER_ERROR;
}
+#ifdef HAVE_OCSP_STAPLING
+ ssl_stapling_ex_init();
+#endif
/*
* initialize session caching
@@ -308,7 +338,7 @@ int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
/*
* initialize servers
*/
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, base_server,
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, base_server, APLOGNO(01887)
"Init: Initializing (virtual) servers for SSL");
for (s = base_server; s; s = s->next) {
@@ -353,10 +383,10 @@ void ssl_init_Engine(server_rec *s, apr_pool_t *p)
if (mc->szCryptoDevice) {
if (!(e = ENGINE_by_id(mc->szCryptoDevice))) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01888)
"Init: Failed to load Crypto Device API `%s'",
mc->szCryptoDevice);
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
ssl_die();
}
@@ -365,14 +395,14 @@ void ssl_init_Engine(server_rec *s, apr_pool_t *p)
}
if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01889)
"Init: Failed to enable Crypto Device API `%s'",
mc->szCryptoDevice);
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
ssl_die();
}
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
- "Init: loaded Crypto Device API `%s'",
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01890)
+ "Init: loaded Crypto Device API `%s'",
mc->szCryptoDevice);
ENGINE_free(e);
@@ -389,8 +419,8 @@ static void ssl_init_server_check(server_rec *s,
* check for important parameters and the
* possibility that the user forgot to set them.
*/
- if (!mctx->pks->cert_files[0]) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ if (!mctx->pks->cert_files[0] && !mctx->pkcs7) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01891)
"No SSL Certificate set [hint: SSLCertificateFile]");
ssl_die();
}
@@ -399,9 +429,13 @@ static void ssl_init_server_check(server_rec *s,
* Check for problematic re-initializations
*/
if (mctx->pks->certs[SSL_AIDX_RSA] ||
- mctx->pks->certs[SSL_AIDX_DSA])
+ mctx->pks->certs[SSL_AIDX_DSA]
+#ifndef OPENSSL_NO_EC
+ || mctx->pks->certs[SSL_AIDX_ECC]
+#endif
+ )
{
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01892)
"Illegal attempt to re-initialise SSL for server "
"(SSLEngine On should go in the VirtualHost, not in global scope.)");
ssl_die();
@@ -417,7 +451,7 @@ static void ssl_init_ctx_tls_extensions(server_rec *s,
/*
* Configure TLS extensions support
*/
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01893)
"Configuring TLS extension handling");
/*
@@ -426,12 +460,21 @@ static void ssl_init_ctx_tls_extensions(server_rec *s,
if (!SSL_CTX_set_tlsext_servername_callback(mctx->ssl_ctx,
ssl_callback_ServerNameIndication) ||
!SSL_CTX_set_tlsext_servername_arg(mctx->ssl_ctx, mctx)) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01894)
"Unable to initialize TLS servername extension "
"callback (incompatible OpenSSL version?)");
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
ssl_die();
}
+
+#ifdef HAVE_OCSP_STAPLING
+ /*
+ * OCSP Stapling support, status_request extension
+ */
+ if ((mctx->pkp == FALSE) && (mctx->stapling_enabled == TRUE)) {
+ modssl_init_stapling(s, p, ptemp, mctx);
+ }
+#endif
}
#endif
@@ -450,44 +493,43 @@ static void ssl_init_ctx_protocol(server_rec *s,
* Create the new per-server SSL context
*/
if (protocol == SSL_PROTOCOL_NONE) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02231)
"No SSL protocols available [hint: SSLProtocol]");
ssl_die();
}
cp = apr_pstrcat(p,
- (protocol & SSL_PROTOCOL_SSLV2 ? "SSLv2, " : ""),
(protocol & SSL_PROTOCOL_SSLV3 ? "SSLv3, " : ""),
(protocol & SSL_PROTOCOL_TLSV1 ? "TLSv1, " : ""),
NULL);
cp[strlen(cp)-2] = NUL;
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_TRACE3, 0, s,
"Creating new SSL context (protocols: %s)", cp);
-#ifndef OPENSSL_NO_SSL2
- if (protocol == SSL_PROTOCOL_SSLV2) {
+ if (protocol == SSL_PROTOCOL_SSLV3) {
method = mctx->pkp ?
- SSLv2_client_method() : /* proxy */
- SSLv2_server_method(); /* server */
- ctx = SSL_CTX_new(method); /* only SSLv2 is left */
+ SSLv3_client_method() : /* proxy */
+ SSLv3_server_method(); /* server */
}
- else
-#endif
- {
+ else if (protocol == SSL_PROTOCOL_TLSV1) {
+ method = mctx->pkp ?
+ TLSv1_client_method() : /* proxy */
+ TLSv1_server_method(); /* server */
+ }
+ else { /* For multiple protocols, we need a flexible method */
method = mctx->pkp ?
SSLv23_client_method() : /* proxy */
SSLv23_server_method(); /* server */
- ctx = SSL_CTX_new(method); /* be more flexible */
}
+ ctx = SSL_CTX_new(method);
mctx->ssl_ctx = ctx;
SSL_CTX_set_options(ctx, SSL_OP_ALL);
- if (!(protocol & SSL_PROTOCOL_SSLV2)) {
- SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
- }
+ /* always disable SSLv2, as per RFC 6176 */
+ SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
if (!(protocol & SSL_PROTOCOL_SSLV3)) {
SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3);
@@ -523,6 +565,12 @@ static void ssl_init_ctx_protocol(server_rec *s,
*/
SSL_CTX_set_options(ctx, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
#endif
+
+#ifdef SSL_MODE_RELEASE_BUFFERS
+ /* If httpd is configured to reduce mem usage, ask openssl to do so, too */
+ if (ap_max_mem_free != APR_ALLOCATOR_MAX_FREE_UNLIMITED)
+ SSL_CTX_set_mode(ctx, SSL_MODE_RELEASE_BUFFERS);
+#endif
}
static void ssl_init_ctx_session_cache(server_rec *s,
@@ -532,20 +580,14 @@ static void ssl_init_ctx_session_cache(server_rec *s,
{
SSL_CTX *ctx = mctx->ssl_ctx;
SSLModConfigRec *mc = myModConfig(s);
- long cache_mode = SSL_SESS_CACHE_OFF;
- if (mc->nSessionCacheMode != SSL_SCMODE_NONE) {
- /* SSL_SESS_CACHE_NO_INTERNAL will force OpenSSL
- * to ignore process local-caching and
- * to always get/set/delete sessions using mod_ssl's callbacks.
- */
- cache_mode = SSL_SESS_CACHE_SERVER|SSL_SESS_CACHE_NO_INTERNAL;
- }
- SSL_CTX_set_session_cache_mode(ctx, cache_mode);
+ SSL_CTX_set_session_cache_mode(ctx, mc->sesscache_mode);
- SSL_CTX_sess_set_new_cb(ctx, ssl_callback_NewSessionCacheEntry);
- SSL_CTX_sess_set_get_cb(ctx, ssl_callback_GetSessionCacheEntry);
- SSL_CTX_sess_set_remove_cb(ctx, ssl_callback_DelSessionCacheEntry);
+ if (mc->sesscache) {
+ SSL_CTX_sess_set_new_cb(ctx, ssl_callback_NewSessionCacheEntry);
+ SSL_CTX_sess_set_get_cb(ctx, ssl_callback_GetSessionCacheEntry);
+ SSL_CTX_sess_set_remove_cb(ctx, ssl_callback_DelSessionCacheEntry);
+ }
}
static void ssl_init_ctx_callbacks(server_rec *s,
@@ -557,6 +599,9 @@ static void ssl_init_ctx_callbacks(server_rec *s,
SSL_CTX_set_tmp_rsa_callback(ctx, ssl_callback_TmpRSA);
SSL_CTX_set_tmp_dh_callback(ctx, ssl_callback_TmpDH);
+#ifndef OPENSSL_NO_EC
+ SSL_CTX_set_tmp_ecdh_callback(ctx,ssl_callback_TmpECDH);
+#endif
SSL_CTX_set_info_callback(ctx, ssl_callback_Info);
}
@@ -598,17 +643,17 @@ static void ssl_init_ctx_verify(server_rec *s,
* Configure Client Authentication details
*/
if (mctx->auth.ca_cert_file || mctx->auth.ca_cert_path) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s,
"Configuring client authentication");
if (!SSL_CTX_load_verify_locations(ctx,
- MODSSL_PCHAR_CAST mctx->auth.ca_cert_file,
- MODSSL_PCHAR_CAST mctx->auth.ca_cert_path))
+ mctx->auth.ca_cert_file,
+ mctx->auth.ca_cert_path))
{
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01895)
"Unable to configure verify locations "
"for client authentication");
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
ssl_die();
}
@@ -620,8 +665,8 @@ static void ssl_init_ctx_verify(server_rec *s,
ca_list = ssl_init_FindCAList(s, ptemp,
mctx->auth.ca_cert_file,
mctx->auth.ca_cert_path);
- if (!ca_list) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ if (sk_X509_NAME_num(ca_list) <= 0) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01896)
"Unable to determine list of acceptable "
"CA certificates for client authentication");
ssl_die();
@@ -638,7 +683,7 @@ static void ssl_init_ctx_verify(server_rec *s,
ca_list = SSL_CTX_get_client_CA_list(ctx);
if (sk_X509_NAME_num(ca_list) == 0) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(01897)
"Init: Oops, you want to request client "
"authentication, but no CAs are known for "
"verification!? [Hint: SSLCACertificate*]");
@@ -661,14 +706,14 @@ static void ssl_init_ctx_cipher_suite(server_rec *s,
return;
}
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_TRACE1, 0, s,
"Configuring permitted SSL ciphers [%s]",
suite);
- if (!SSL_CTX_set_cipher_list(ctx, MODSSL_PCHAR_CAST suite)) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ if (!SSL_CTX_set_cipher_list(ctx, suite)) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01898)
"Unable to configure permitted SSL ciphers");
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
ssl_die();
}
}
@@ -678,28 +723,67 @@ static void ssl_init_ctx_crl(server_rec *s,
apr_pool_t *ptemp,
modssl_ctx_t *mctx)
{
+ X509_STORE *store = SSL_CTX_get_cert_store(mctx->ssl_ctx);
+ unsigned long crlflags = 0;
+ char *cfgp = mctx->pkp ? "SSLProxy" : "SSL";
+
/*
* Configure Certificate Revocation List (CRL) Details
*/
if (!(mctx->crl_file || mctx->crl_path)) {
+ if (mctx->crl_check_mode == SSL_CRLCHECK_LEAF ||
+ mctx->crl_check_mode == SSL_CRLCHECK_CHAIN) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01899)
+ "Host %s: CRL checking has been enabled, but "
+ "neither %sCARevocationFile nor %sCARevocationPath "
+ "is configured", mctx->sc->vhost_id, cfgp, cfgp);
+ ssl_die();
+ }
return;
}
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01900)
"Configuring certificate revocation facility");
- mctx->crl =
- SSL_X509_STORE_create((char *)mctx->crl_file,
- (char *)mctx->crl_path);
-
- if (!mctx->crl) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
- "Unable to configure X.509 CRL storage "
- "for certificate revocation");
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+ if (!store || !X509_STORE_load_locations(store, mctx->crl_file,
+ mctx->crl_path)) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01901)
+ "Host %s: unable to configure X.509 CRL storage "
+ "for certificate revocation", mctx->sc->vhost_id);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
ssl_die();
}
+
+ switch (mctx->crl_check_mode) {
+ case SSL_CRLCHECK_LEAF:
+ crlflags = X509_V_FLAG_CRL_CHECK;
+ break;
+ case SSL_CRLCHECK_CHAIN:
+ crlflags = X509_V_FLAG_CRL_CHECK|X509_V_FLAG_CRL_CHECK_ALL;
+ break;
+ default:
+ crlflags = 0;
+ }
+
+ if (crlflags) {
+ X509_STORE_set_flags(store, crlflags);
+ } else {
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(01902)
+ "Host %s: X.509 CRL storage locations configured, "
+ "but CRL checking (%sCARevocationCheck) is not "
+ "enabled", mctx->sc->vhost_id, cfgp);
+ }
+}
+
+static void ssl_init_ctx_pkcs7_cert_chain(server_rec *s, modssl_ctx_t *mctx)
+{
+ STACK_OF(X509) *certs = ssl_read_pkcs7(s, mctx->pkcs7);
+ int n;
+
+ if (!mctx->ssl_ctx->extra_certs)
+ for (n = 1; n < sk_X509_num(certs); ++n)
+ SSL_CTX_add_extra_chain_cert(mctx->ssl_ctx, sk_X509_value(certs, n));
}
static void ssl_init_ctx_cert_chain(server_rec *s,
@@ -711,6 +795,11 @@ static void ssl_init_ctx_cert_chain(server_rec *s,
int i, n;
const char *chain = mctx->cert_chain;
+ if (mctx->pkcs7) {
+ ssl_init_ctx_pkcs7_cert_chain(s, mctx);
+ return;
+ }
+
/*
* Optionally configure extra server certificate chain certificates.
* This is usually done by OpenSSL automatically when one of the
@@ -740,12 +829,12 @@ static void ssl_init_ctx_cert_chain(server_rec *s,
(char *)chain,
skip_first, NULL);
if (n < 0) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01903)
"Failed to configure CA certificate chain!");
ssl_die();
}
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01904)
"Configuring server certificate chain "
"(%d CA certificate%s)",
n, n == 1 ? "" : "s");
@@ -792,24 +881,33 @@ static int ssl_server_import_cert(server_rec *s,
return FALSE;
}
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02232)
"Configuring %s server certificate", type);
ptr = asn1->cpData;
if (!(cert = d2i_X509(NULL, &ptr, asn1->nData))) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02233)
"Unable to import %s server certificate", type);
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
ssl_die();
}
if (SSL_CTX_use_certificate(mctx->ssl_ctx, cert) <= 0) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02234)
"Unable to configure %s server certificate", type);
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
ssl_die();
}
+#ifdef HAVE_OCSP_STAPLING
+ if ((mctx->pkp == FALSE) && (mctx->stapling_enabled == TRUE)) {
+ if (!ssl_stapling_init_cert(s, mctx, cert)) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02235)
+ "Unable to configure server certificate for stapling");
+ }
+ }
+#endif
+
mctx->pks->certs[idx] = cert;
return TRUE;
@@ -824,29 +922,36 @@ static int ssl_server_import_key(server_rec *s,
ssl_asn1_t *asn1;
MODSSL_D2I_PrivateKey_CONST unsigned char *ptr;
const char *type = ssl_asn1_keystr(idx);
- int pkey_type = (idx == SSL_AIDX_RSA) ? EVP_PKEY_RSA : EVP_PKEY_DSA;
+ int pkey_type;
EVP_PKEY *pkey;
+#ifndef OPENSSL_NO_EC
+ if (idx == SSL_AIDX_ECC)
+ pkey_type = EVP_PKEY_EC;
+ else
+#endif
+ pkey_type = (idx == SSL_AIDX_RSA) ? EVP_PKEY_RSA : EVP_PKEY_DSA;
+
if (!(asn1 = ssl_asn1_table_get(mc->tPrivateKey, id))) {
return FALSE;
}
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02236)
"Configuring %s server private key", type);
ptr = asn1->cpData;
if (!(pkey = d2i_PrivateKey(pkey_type, NULL, &ptr, asn1->nData)))
{
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02237)
"Unable to import %s server private key", type);
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
ssl_die();
}
if (SSL_CTX_use_PrivateKey(mctx->ssl_ctx, pkey) <= 0) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02238)
"Unable to configure %s server private key", type);
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
ssl_die();
}
@@ -859,9 +964,9 @@ static int ssl_server_import_key(server_rec *s,
if (pubkey && EVP_PKEY_missing_parameters(pubkey)) {
EVP_PKEY_copy_parameters(pubkey, pkey);
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02239)
"Copying DSA parameters from private key to certificate");
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s);
EVP_PKEY_free(pubkey);
}
}
@@ -877,7 +982,7 @@ static void ssl_check_public_cert(server_rec *s,
int type)
{
int is_ca, pathlen;
- char *cn;
+ apr_array_header_t *ids;
if (!cert) {
return;
@@ -888,7 +993,7 @@ static void ssl_check_public_cert(server_rec *s,
*/
if (SSL_X509_isSGC(cert)) {
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01905)
"%s server certificate enables "
"Server Gated Cryptography (SGC)",
ssl_asn1_keystr(type));
@@ -896,37 +1001,69 @@ static void ssl_check_public_cert(server_rec *s,
if (SSL_X509_getBC(cert, &is_ca, &pathlen)) {
if (is_ca) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(01906)
"%s server certificate is a CA certificate "
"(BasicConstraints: CA == TRUE !?)",
ssl_asn1_keystr(type));
}
if (pathlen > 0) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(01907)
"%s server certificate is not a leaf certificate "
"(BasicConstraints: pathlen == %d > 0 !?)",
ssl_asn1_keystr(type), pathlen);
}
}
- if (SSL_X509_getCN(ptemp, cert, &cn)) {
- int fnm_flags = APR_FNM_PERIOD|APR_FNM_CASE_BLIND;
-
- if (apr_fnmatch_test(cn)) {
- if (apr_fnmatch(cn, s->server_hostname,
- fnm_flags) == APR_FNM_NOMATCH) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
- "%s server certificate wildcard CommonName "
- "(CN) `%s' does NOT match server name!?",
- ssl_asn1_keystr(type), cn);
+ /*
+ * Check if the server name is covered by the certificate.
+ * Consider both dNSName entries in the subjectAltName extension
+ * and, as a fallback, commonName attributes in the subject DN.
+ * (DNS-IDs and CN-IDs as defined in RFC 6125).
+ */
+ if (SSL_X509_getIDs(ptemp, cert, &ids)) {
+ char *cp;
+ int i;
+ char **id = (char **)ids->elts;
+ BOOL is_wildcard, matched = FALSE;
+
+ for (i = 0; i < ids->nelts; i++) {
+ if (!id[i])
+ continue;
+
+ /*
+ * Determine if it is a wildcard ID - we're restrictive
+ * in the sense that we require the wildcard character to be
+ * THE left-most label (i.e., the ID must start with "*.")
+ */
+ is_wildcard = (*id[i] == '*' && *(id[i]+1) == '.') ? TRUE : FALSE;
+
+ /*
+ * If the ID includes a wildcard character, check if it matches
+ * for the left-most DNS label (i.e., the wildcard character
+ * is not allowed to match a dot). Otherwise, try a simple
+ * string compare, case insensitively.
+ */
+ if ((is_wildcard == TRUE &&
+ (cp = strchr(s->server_hostname, '.')) &&
+ !strcasecmp(id[i]+1, cp)) ||
+ !strcasecmp(id[i], s->server_hostname)) {
+ matched = TRUE;
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01908)
+ "%sID '%s' in %s certificate configured "
+ "for %s matches server name",
+ is_wildcard ? "Wildcard " : "",
+ id[i], ssl_asn1_keystr(type),
+ (mySrvConfig(s))->vhost_id);
+ break;
}
}
- else if (strNE(s->server_hostname, cn)) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
- "%s server certificate CommonName (CN) `%s' "
- "does NOT match server name!?",
- ssl_asn1_keystr(type), cn);
+
+ if (matched == FALSE) {
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(01909)
+ "%s certificate configured for %s does NOT include "
+ "an ID which matches the server name",
+ ssl_asn1_keystr(type), (mySrvConfig(s))->vhost_id);
}
}
}
@@ -937,19 +1074,39 @@ static void ssl_init_server_certs(server_rec *s,
modssl_ctx_t *mctx)
{
const char *rsa_id, *dsa_id;
+#ifndef OPENSSL_NO_EC
+ const char *ecc_id;
+#endif
const char *vhost_id = mctx->sc->vhost_id;
int i;
int have_rsa, have_dsa;
+#ifndef OPENSSL_NO_EC
+ int have_ecc;
+#endif
rsa_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_RSA);
dsa_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_DSA);
+#ifndef OPENSSL_NO_EC
+ ecc_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_ECC);
+#endif
have_rsa = ssl_server_import_cert(s, mctx, rsa_id, SSL_AIDX_RSA);
have_dsa = ssl_server_import_cert(s, mctx, dsa_id, SSL_AIDX_DSA);
+#ifndef OPENSSL_NO_EC
+ have_ecc = ssl_server_import_cert(s, mctx, ecc_id, SSL_AIDX_ECC);
+#endif
- if (!(have_rsa || have_dsa)) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ if (!(have_rsa || have_dsa
+#ifndef OPENSSL_NO_EC
+ || have_ecc
+#endif
+)) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01910)
+#ifndef OPENSSL_NO_EC
+ "Oops, no RSA, DSA or ECC server certificate found "
+#else
"Oops, no RSA or DSA server certificate found "
+#endif
"for '%s:%d'?!", s->server_hostname, s->port);
ssl_die();
}
@@ -960,13 +1117,81 @@ static void ssl_init_server_certs(server_rec *s,
have_rsa = ssl_server_import_key(s, mctx, rsa_id, SSL_AIDX_RSA);
have_dsa = ssl_server_import_key(s, mctx, dsa_id, SSL_AIDX_DSA);
+#ifndef OPENSSL_NO_EC
+ have_ecc = ssl_server_import_key(s, mctx, ecc_id, SSL_AIDX_ECC);
+#endif
- if (!(have_rsa || have_dsa)) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ if (!(have_rsa || have_dsa
+#ifndef OPENSSL_NO_EC
+ || have_ecc
+#endif
+ )) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01911)
+#ifndef OPENSSL_NO_EC
+ "Oops, no RSA, DSA or ECC server private key found?!");
+#else
"Oops, no RSA or DSA server private key found?!");
+#endif
+ ssl_die();
+ }
+}
+
+#ifdef HAVE_TLS_SESSION_TICKETS
+static void ssl_init_ticket_key(server_rec *s,
+ apr_pool_t *p,
+ apr_pool_t *ptemp,
+ modssl_ctx_t *mctx)
+{
+ apr_status_t rv;
+ apr_file_t *fp;
+ apr_size_t len;
+ char buf[TLSEXT_TICKET_KEY_LEN];
+ char *path;
+ modssl_ticket_key_t *ticket_key = mctx->ticket_key;
+
+ if (!ticket_key->file_path) {
+ return;
+ }
+
+ path = ap_server_root_relative(p, ticket_key->file_path);
+
+ rv = apr_file_open(&fp, path, APR_READ|APR_BINARY,
+ APR_OS_DEFAULT, ptemp);
+
+ if (rv != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02286)
+ "Failed to open ticket key file %s: (%d) %pm",
+ path, rv, &rv);
+ ssl_die();
+ }
+
+ rv = apr_file_read_full(fp, &buf[0], TLSEXT_TICKET_KEY_LEN, &len);
+
+ if (rv != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02287)
+ "Failed to read %d bytes from %s: (%d) %pm",
+ TLSEXT_TICKET_KEY_LEN, path, rv, &rv);
+ ssl_die();
+ }
+
+ memcpy(ticket_key->key_name, buf, 16);
+ memcpy(ticket_key->hmac_secret, buf + 16, 16);
+ memcpy(ticket_key->aes_key, buf + 32, 16);
+
+ if (!SSL_CTX_set_tlsext_ticket_key_cb(mctx->ssl_ctx,
+ ssl_callback_SessionTicket)) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01913)
+ "Unable to initialize TLS session ticket key callback "
+ "(incompatible OpenSSL version?)");
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
ssl_die();
}
+
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(02288)
+ "TLS session ticket key for %s successfully loaded from %s",
+ (mySrvConfig(s))->vhost_id, path);
}
+#endif
static void ssl_init_proxy_certs(server_rec *s,
apr_pool_t *p,
@@ -976,6 +1201,9 @@ static void ssl_init_proxy_certs(server_rec *s,
int n, ncerts = 0;
STACK_OF(X509_INFO) *sk;
modssl_pk_proxy_t *pkp = mctx->pkp;
+ STACK_OF(X509) *chain;
+ X509_STORE_CTX *sctx;
+ X509_STORE *store = SSL_CTX_get_cert_store(mctx->ssl_ctx);
SSL_CTX_set_client_cert_cb(mctx->ssl_ctx,
ssl_callback_proxy_cert);
@@ -996,7 +1224,7 @@ static void ssl_init_proxy_certs(server_rec *s,
if ((ncerts = sk_X509_INFO_num(sk)) <= 0) {
sk_X509_INFO_free(sk);
- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(02206)
"no client certs found for SSL proxy");
return;
}
@@ -1008,7 +1236,7 @@ static void ssl_init_proxy_certs(server_rec *s,
if (!inf->x509 || !inf->x_pkey) {
sk_X509_INFO_free(sk);
- ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s, APLOGNO(02252)
"incomplete client cert configured for SSL proxy "
"(missing or encrypted private key?)");
ssl_die();
@@ -1016,10 +1244,82 @@ static void ssl_init_proxy_certs(server_rec *s,
}
}
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02207)
"loaded %d client certs for SSL proxy",
ncerts);
pkp->certs = sk;
+
+
+ if (!pkp->ca_cert_file || !store) {
+ return;
+ }
+
+ /* Load all of the CA certs and construct a chain */
+ pkp->ca_certs = (STACK_OF(X509) **) apr_pcalloc(p, ncerts * sizeof(sk));
+ sctx = X509_STORE_CTX_new();
+
+ if (!sctx) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02208)
+ "SSL proxy client cert initialization failed");
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
+ ssl_die();
+ }
+
+ X509_STORE_load_locations(store, pkp->ca_cert_file, NULL);
+
+ for (n = 0; n < ncerts; n++) {
+ int i;
+
+ X509_INFO *inf = sk_X509_INFO_value(pkp->certs, n);
+ X509_STORE_CTX_init(sctx, store, inf->x509, NULL);
+
+ /* Attempt to verify the client cert */
+ if (X509_verify_cert(sctx) != 1) {
+ int err = X509_STORE_CTX_get_error(sctx);
+ ssl_log_xerror(SSLLOG_MARK, APLOG_WARNING, 0, ptemp, s, inf->x509,
+ APLOGNO(02270) "SSL proxy client cert chain "
+ "verification failed: %s :",
+ X509_verify_cert_error_string(err));
+ }
+
+ /* Clear X509_verify_cert errors */
+ ERR_clear_error();
+
+ /* Obtain a copy of the verified chain */
+ chain = X509_STORE_CTX_get1_chain(sctx);
+
+ if (chain != NULL) {
+ /* Discard end entity cert from the chain */
+ X509_free(sk_X509_shift(chain));
+
+ if ((i = sk_X509_num(chain)) > 0) {
+ /* Store the chain for later use */
+ pkp->ca_certs[n] = chain;
+ }
+ else {
+ /* Discard empty chain */
+ sk_X509_pop_free(chain, X509_free);
+ pkp->ca_certs[n] = NULL;
+ }
+
+ ssl_log_xerror(SSLLOG_MARK, APLOG_DEBUG, 0, ptemp, s, inf->x509,
+ APLOGNO(02271)
+ "loaded %i intermediate CA%s for cert %i: ",
+ i, i == 1 ? "" : "s", n);
+ if (i > 0) {
+ int j;
+ for (j = 0; j < i; j++) {
+ ssl_log_xerror(SSLLOG_MARK, APLOG_DEBUG, 0, ptemp, s,
+ sk_X509_value(chain, j), "%i:", j);
+ }
+ }
+ }
+
+ /* get ready for next X509_STORE_CTX_init */
+ X509_STORE_CTX_cleanup(sctx);
+ }
+
+ X509_STORE_CTX_free(sctx);
}
static void ssl_init_proxy_ctx(server_rec *s,
@@ -1042,6 +1342,10 @@ static void ssl_init_server_ctx(server_rec *s,
ssl_init_ctx(s, p, ptemp, sc->server);
ssl_init_server_certs(s, p, ptemp, sc->server);
+
+#ifdef HAVE_TLS_SESSION_TICKETS
+ ssl_init_ticket_key(s, p, ptemp, sc->server);
+#endif
}
/*
@@ -1055,8 +1359,8 @@ void ssl_init_ConfigureServer(server_rec *s,
/* Initialize the server if SSL is enabled or optional.
*/
if ((sc->enabled == SSL_ENABLED_TRUE) || (sc->enabled == SSL_ENABLED_OPTIONAL)) {
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
- "Configuring server for SSL protocol");
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01914)
+ "Configuring server %s for SSL protocol", sc->vhost_id);
ssl_init_server_ctx(s, p, ptemp, sc);
}
@@ -1084,7 +1388,7 @@ void ssl_init_CheckServers(server_rec *base_server, apr_pool_t *p)
if ((sc->enabled == SSL_ENABLED_TRUE) && (s->port == DEFAULT_HTTP_PORT)) {
ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
- base_server,
+ base_server, APLOGNO(01915)
"Init: (%s) You configured HTTPS(%d) "
"on the standard HTTP(%d) port!",
ssl_util_vhostid(p, s),
@@ -1093,7 +1397,7 @@ void ssl_init_CheckServers(server_rec *base_server, apr_pool_t *p)
if ((sc->enabled == SSL_ENABLED_FALSE) && (s->port == DEFAULT_HTTPS_PORT)) {
ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
- base_server,
+ base_server, APLOGNO(01916)
"Init: (%s) You configured HTTP(%d) "
"on the standard HTTPS(%d) port!",
ssl_util_vhostid(p, s),
@@ -1123,11 +1427,11 @@ void ssl_init_CheckServers(server_rec *base_server, apr_pool_t *p)
klen = strlen(key);
if ((ps = (server_rec *)apr_hash_get(table, key, klen))) {
- ap_log_error(APLOG_MARK,
+ ap_log_error(APLOG_MARK,
#ifdef OPENSSL_NO_TLSEXT
- APLOG_WARNING,
+ APLOG_WARNING,
#else
- APLOG_DEBUG,
+ APLOG_DEBUG,
#endif
0,
base_server,
@@ -1151,7 +1455,7 @@ void ssl_init_CheckServers(server_rec *base_server, apr_pool_t *p)
}
if (conflict) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, base_server,
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, base_server, APLOGNO(01917)
#ifdef OPENSSL_NO_TLSEXT
"Init: You should not use name-based "
"virtual hosts in conjunction with SSL!!");
@@ -1163,39 +1467,32 @@ void ssl_init_CheckServers(server_rec *base_server, apr_pool_t *p)
}
}
-#ifdef SSLC_VERSION_NUMBER
-static int ssl_init_FindCAList_X509NameCmp(char **a, char **b)
-{
- return(X509_NAME_cmp((void*)*a, (void*)*b));
-}
-#else
-static int ssl_init_FindCAList_X509NameCmp(const X509_NAME * const *a,
+static int ssl_init_FindCAList_X509NameCmp(const X509_NAME * const *a,
const X509_NAME * const *b)
{
return(X509_NAME_cmp(*a, *b));
}
-#endif
static void ssl_init_PushCAList(STACK_OF(X509_NAME) *ca_list,
- server_rec *s, const char *file)
+ server_rec *s, apr_pool_t *ptemp,
+ const char *file)
{
int n;
STACK_OF(X509_NAME) *sk;
sk = (STACK_OF(X509_NAME) *)
- SSL_load_client_CA_file(MODSSL_PCHAR_CAST file);
+ SSL_load_client_CA_file(file);
if (!sk) {
return;
}
for (n = 0; n < sk_X509_NAME_num(sk); n++) {
- char name_buf[256];
X509_NAME *name = sk_X509_NAME_value(sk, n);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02209)
"CA certificate: %s",
- X509_NAME_oneline(name, name_buf, sizeof(name_buf)));
+ SSL_X509_NAME_to_string(ptemp, name, 0));
/*
* note that SSL_load_client_CA_file() checks for duplicates,
@@ -1233,7 +1530,16 @@ STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s,
* Process CA certificate bundle file
*/
if (ca_file) {
- ssl_init_PushCAList(ca_list, s, ca_file);
+ ssl_init_PushCAList(ca_list, s, ptemp, ca_file);
+ /*
+ * If ca_list is still empty after trying to load ca_file
+ * then the file failed to load, and users should hear about that.
+ */
+ if (sk_X509_NAME_num(ca_list) == 0) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02210)
+ "Failed to load SSLCACertificateFile: %s", ca_file);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s);
+ }
}
/*
@@ -1246,7 +1552,7 @@ STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s,
apr_status_t rv;
if ((rv = apr_dir_open(&dir, ca_path, ptemp)) != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
+ ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(02211)
"Failed to open Certificate Path `%s'",
ca_path);
ssl_die();
@@ -1258,7 +1564,7 @@ STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s,
continue; /* don't try to load directories */
}
file = apr_pstrcat(ptemp, ca_path, "/", direntry.name, NULL);
- ssl_init_PushCAList(ca_list, s, file);
+ ssl_init_PushCAList(ca_list, s, ptemp, file);
}
apr_dir_close(dir);
@@ -1282,6 +1588,9 @@ void ssl_init_Child(apr_pool_t *p, server_rec *s)
/* open the mutex lockfile */
ssl_mutex_reinit(s, p);
+#ifdef HAVE_OCSP_STAPLING
+ ssl_stapling_mutex_reinit(s, p);
+#endif
}
#define MODSSL_CFG_ITEM_FREE(func, item) \
@@ -1292,8 +1601,6 @@ void ssl_init_Child(apr_pool_t *p, server_rec *s)
static void ssl_init_ctx_cleanup(modssl_ctx_t *mctx)
{
- MODSSL_CFG_ITEM_FREE(X509_STORE_free, mctx->crl);
-
MODSSL_CFG_ITEM_FREE(SSL_CTX_free, mctx->ssl_ctx);
}
diff --git a/modules/ssl/ssl_engine_io.c b/modules/ssl/ssl_engine_io.c
index e2d33909..2ffe21f4 100644
--- a/modules/ssl/ssl_engine_io.c
+++ b/modules/ssl/ssl_engine_io.c
@@ -102,17 +102,13 @@ typedef struct {
BIO *pbioWrite;
ap_filter_t *pInputFilter;
ap_filter_t *pOutputFilter;
- int nobuffer; /* non-zero to prevent buffering */
SSLConnRec *config;
} ssl_filter_ctx_t;
typedef struct {
ssl_filter_ctx_t *filter_ctx;
conn_rec *c;
- apr_bucket_brigade *bb;
- apr_size_t length;
- char buffer[AP_IOBUFSIZE];
- apr_size_t blen;
+ apr_bucket_brigade *bb; /* Brigade used as a buffer. */
apr_status_t rc;
} bio_filter_out_ctx_t;
@@ -124,35 +120,15 @@ static bio_filter_out_ctx_t *bio_filter_out_ctx_new(ssl_filter_ctx_t *filter_ctx
outctx->filter_ctx = filter_ctx;
outctx->c = c;
outctx->bb = apr_brigade_create(c->pool, c->bucket_alloc);
- outctx->blen = 0;
- outctx->length = 0;
return outctx;
}
-static int bio_filter_out_flush(BIO *bio)
+/* Pass an output brigade down the filter stack; returns 1 on success
+ * or -1 on failure. */
+static int bio_filter_out_pass(bio_filter_out_ctx_t *outctx)
{
- bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)(bio->ptr);
- apr_bucket *e;
-
- if (!(outctx->blen || outctx->length)) {
- outctx->rc = APR_SUCCESS;
- return 1;
- }
-
- if (outctx->blen) {
- e = apr_bucket_transient_create(outctx->buffer, outctx->blen,
- outctx->bb->bucket_alloc);
- /* we filled this buffer first so add it to the
- * head of the brigade
- */
- APR_BRIGADE_INSERT_HEAD(outctx->bb, e);
- outctx->blen = 0;
- }
-
- outctx->length = 0;
- e = apr_bucket_flush_create(outctx->bb->bucket_alloc);
- APR_BRIGADE_INSERT_TAIL(outctx->bb, e);
+ AP_DEBUG_ASSERT(!APR_BRIGADE_EMPTY(outctx->bb));
outctx->rc = ap_pass_brigade(outctx->filter_ctx->pOutputFilter->next,
outctx->bb);
@@ -163,6 +139,21 @@ static int bio_filter_out_flush(BIO *bio)
return (outctx->rc == APR_SUCCESS) ? 1 : -1;
}
+/* Send a FLUSH bucket down the output filter stack; returns 1 on
+ * success, -1 on failure. */
+static int bio_filter_out_flush(BIO *bio)
+{
+ bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)(bio->ptr);
+ apr_bucket *e;
+
+ AP_DEBUG_ASSERT(APR_BRIGADE_EMPTY(outctx->bb));
+
+ e = apr_bucket_flush_create(outctx->bb->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(outctx->bb, e);
+
+ return bio_filter_out_pass(outctx);
+}
+
static int bio_filter_create(BIO *bio)
{
bio->shutdown = 1;
@@ -194,45 +185,27 @@ static int bio_filter_out_read(BIO *bio, char *out, int outl)
static int bio_filter_out_write(BIO *bio, const char *in, int inl)
{
bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)(bio->ptr);
-
+ apr_bucket *e;
+
/* Abort early if the client has initiated a renegotiation. */
if (outctx->filter_ctx->config->reneg_state == RENEG_ABORT) {
outctx->rc = APR_ECONNABORTED;
return -1;
}
-
+
/* when handshaking we'll have a small number of bytes.
* max size SSL will pass us here is about 16k.
* (16413 bytes to be exact)
*/
BIO_clear_retry_flags(bio);
- if (!outctx->length && (inl + outctx->blen < sizeof(outctx->buffer)) &&
- !outctx->filter_ctx->nobuffer) {
- /* the first two SSL_writes (of 1024 and 261 bytes)
- * need to be in the same packet (vec[0].iov_base)
- */
- /* XXX: could use apr_brigade_write() to make code look cleaner
- * but this way we avoid the malloc(APR_BUCKET_BUFF_SIZE)
- * and free() of it later
- */
- memcpy(&outctx->buffer[outctx->blen], in, inl);
- outctx->blen += inl;
- }
- else {
- /* pass along the encrypted data
- * need to flush since we're using SSL's malloc-ed buffer
- * which will be overwritten once we leave here
- */
- apr_bucket *bucket = apr_bucket_transient_create(in, inl,
- outctx->bb->bucket_alloc);
-
- outctx->length += inl;
- APR_BRIGADE_INSERT_TAIL(outctx->bb, bucket);
+ /* Use a transient bucket for the output data - any downstream
+ * filter must setaside if necessary. */
+ e = apr_bucket_transient_create(in, inl, outctx->bb->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(outctx->bb, e);
- if (bio_filter_out_flush(bio) < 0) {
- return -1;
- }
+ if (bio_filter_out_pass(outctx) < 0) {
+ return -1;
}
return inl;
@@ -241,39 +214,27 @@ static int bio_filter_out_write(BIO *bio, const char *in, int inl)
static long bio_filter_out_ctrl(BIO *bio, int cmd, long num, void *ptr)
{
long ret = 1;
- char **pptr;
-
bio_filter_out_ctx_t *outctx = (bio_filter_out_ctx_t *)(bio->ptr);
switch (cmd) {
- case BIO_CTRL_RESET:
- outctx->blen = outctx->length = 0;
- break;
- case BIO_CTRL_EOF:
- ret = (long)((outctx->blen + outctx->length) == 0);
- break;
- case BIO_C_SET_BUF_MEM_EOF_RETURN:
- outctx->blen = outctx->length = (apr_size_t)num;
+ case BIO_CTRL_RESET:
+ case BIO_CTRL_EOF:
+ case BIO_C_SET_BUF_MEM_EOF_RETURN:
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, outctx->c,
+ "output bio: unhandled control %d", cmd);
+ ret = 0;
break;
- case BIO_CTRL_INFO:
- ret = (long)(outctx->blen + outctx->length);
- if (ptr) {
- pptr = (char **)ptr;
- *pptr = (char *)&(outctx->buffer[0]);
- }
+ case BIO_CTRL_WPENDING:
+ case BIO_CTRL_PENDING:
+ case BIO_CTRL_INFO:
+ ret = 0;
break;
- case BIO_CTRL_GET_CLOSE:
+ case BIO_CTRL_GET_CLOSE:
ret = (long)bio->shutdown;
break;
case BIO_CTRL_SET_CLOSE:
bio->shutdown = (int)num;
break;
- case BIO_CTRL_WPENDING:
- ret = 0L;
- break;
- case BIO_CTRL_PENDING:
- ret = (long)(outctx->blen + outctx->length);
- break;
case BIO_CTRL_FLUSH:
ret = bio_filter_out_flush(bio);
break;
@@ -316,9 +277,7 @@ static BIO_METHOD bio_filter_out_method = {
bio_filter_out_ctrl,
bio_filter_create,
bio_filter_destroy,
-#ifdef OPENSSL_VERSION_NUMBER
- NULL /* sslc does not have the callback_ctrl field */
-#endif
+ NULL
};
typedef struct {
@@ -570,9 +529,7 @@ static BIO_METHOD bio_filter_in_method = {
NULL, /* ctrl is never called */
bio_filter_create,
bio_filter_destroy,
-#ifdef OPENSSL_VERSION_NUMBER
- NULL /* sslc does not have the callback_ctrl field */
-#endif
+ NULL
};
@@ -680,7 +637,7 @@ static apr_status_t ssl_io_input_read(bio_filter_in_ctx_t *inctx,
* data from network filter.
*
* (This is usually the case when the client forces an SSL
- * renegotation which is handled implicitly by OpenSSL.)
+ * renegotiation which is handled implicitly by OpenSSL.)
*/
inctx->rc = APR_EAGAIN;
@@ -707,7 +664,7 @@ static apr_status_t ssl_io_input_read(bio_filter_in_ctx_t *inctx,
continue; /* Blocking and nothing yet? Try again. */
}
else {
- ap_log_cerror(APLOG_MARK, APLOG_INFO, inctx->rc, c,
+ ap_log_cerror(APLOG_MARK, APLOG_INFO, inctx->rc, c, APLOGNO(01991)
"SSL input filter read failed.");
}
}
@@ -715,9 +672,9 @@ static apr_status_t ssl_io_input_read(bio_filter_in_ctx_t *inctx,
/*
* Log SSL errors and any unexpected conditions.
*/
- ap_log_cerror(APLOG_MARK, APLOG_INFO, inctx->rc, c,
+ ap_log_cerror(APLOG_MARK, APLOG_INFO, inctx->rc, c, APLOGNO(01992)
"SSL library error %d reading data", ssl_err);
- ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, mySrvFromConn(c));
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_INFO, mySrvFromConn(c));
}
if (inctx->rc == APR_SUCCESS) {
@@ -729,6 +686,9 @@ static apr_status_t ssl_io_input_read(bio_filter_in_ctx_t *inctx,
return inctx->rc;
}
+/* Read a line of input from the SSL input layer into buffer BUF of
+ * length *LEN; updating *len to reflect the length of the line
+ * including the LF character. */
static apr_status_t ssl_io_input_getline(bio_filter_in_ctx_t *inctx,
char *buf,
apr_size_t *len)
@@ -811,21 +771,21 @@ static apr_status_t ssl_filter_write(ap_filter_t *f,
* data at the network filter.
*
* (This is usually the case when the client forces an SSL
- * renegotation which is handled implicitly by OpenSSL.)
+ * renegotiation which is handled implicitly by OpenSSL.)
*/
outctx->rc = APR_EAGAIN;
}
else if (ssl_err == SSL_ERROR_SYSCALL) {
- ap_log_cerror(APLOG_MARK, APLOG_INFO, outctx->rc, c,
+ ap_log_cerror(APLOG_MARK, APLOG_INFO, outctx->rc, c, APLOGNO(01993)
"SSL output filter write failed.");
}
else /* if (ssl_err == SSL_ERROR_SSL) */ {
/*
* Log SSL errors
*/
- ap_log_cerror(APLOG_MARK, APLOG_INFO, outctx->rc, c,
+ ap_log_cerror(APLOG_MARK, APLOG_INFO, outctx->rc, c, APLOGNO(01994)
"SSL library error %d writing data", ssl_err);
- ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, mySrvFromConn(c));
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_INFO, mySrvFromConn(c));
}
if (outctx->rc == APR_SUCCESS) {
outctx->rc = APR_EGENERAL;
@@ -840,7 +800,7 @@ static apr_status_t ssl_filter_write(ap_filter_t *f,
reason = "likely due to failed renegotiation";
}
- ap_log_cerror(APLOG_MARK, APLOG_INFO, outctx->rc, c,
+ ap_log_cerror(APLOG_MARK, APLOG_INFO, outctx->rc, c, APLOGNO(01995)
"failed to write %" APR_SSIZE_T_FMT
" of %" APR_SIZE_T_FMT " bytes (%s)",
len - (apr_size_t)res, len, reason);
@@ -865,6 +825,14 @@ static apr_status_t ssl_filter_write(ap_filter_t *f,
sizeof(HTTP_ON_HTTPS_PORT) - 1, \
alloc)
+/* Custom apr_status_t error code, used when a plain HTTP request is
+ * recevied on an SSL port. */
+#define MODSSL_ERROR_HTTP_ON_HTTPS (APR_OS_START_USERERR + 0)
+
+/* Custom apr_status_t error code, used when the proxy cannot
+ * establish an outgoing SSL connection. */
+#define MODSSL_ERROR_BAD_GATEWAY (APR_OS_START_USERERR + 1)
+
static void ssl_io_filter_disable(SSLConnRec *sslconn, ap_filter_t *f)
{
bio_filter_in_ctx_t *inctx = f->ctx;
@@ -882,12 +850,12 @@ static apr_status_t ssl_io_filter_error(ap_filter_t *f,
apr_bucket *bucket;
switch (status) {
- case HTTP_BAD_REQUEST:
+ case MODSSL_ERROR_HTTP_ON_HTTPS:
/* log the situation */
- ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, f->c,
+ ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, f->c, APLOGNO(01996)
"SSL handshake failed: HTTP spoken on HTTPS port; "
"trying to send HTML error page");
- ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, sslconn->server);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_INFO, sslconn->server);
sslconn->non_ssl_request = 1;
ssl_io_filter_disable(sslconn, f);
@@ -896,7 +864,15 @@ static apr_status_t ssl_io_filter_error(ap_filter_t *f,
bucket = HTTP_ON_HTTPS_PORT_BUCKET(f->c->bucket_alloc);
break;
- default:
+ case MODSSL_ERROR_BAD_GATEWAY:
+ bucket = ap_bucket_error_create(HTTP_BAD_REQUEST, NULL,
+ f->c->pool,
+ f->c->bucket_alloc);
+ ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, f->c, APLOGNO(01997)
+ "SSL handshake failed: sending 502");
+ break;
+
+ default:
return status;
}
@@ -909,23 +885,25 @@ static apr_status_t ssl_io_filter_error(ap_filter_t *f,
static const char ssl_io_filter[] = "SSL/TLS Filter";
static const char ssl_io_buffer[] = "SSL/TLS Buffer";
+static const char ssl_io_coalesce[] = "SSL/TLS Coalescing Filter";
/*
* Close the SSL part of the socket connection
* (called immediately _before_ the socket is closed)
* or called with
*/
-static apr_status_t ssl_filter_io_shutdown(ssl_filter_ctx_t *filter_ctx,
- conn_rec *c,
- int abortive)
+static void ssl_filter_io_shutdown(ssl_filter_ctx_t *filter_ctx,
+ conn_rec *c, int abortive)
{
SSL *ssl = filter_ctx->pssl;
const char *type = "";
SSLConnRec *sslconn = myConnConfig(c);
int shutdown_type;
+ int loglevel = APLOG_DEBUG;
+ const char *logno;
if (!ssl) {
- return APR_SUCCESS;
+ return;
}
/*
@@ -967,6 +945,8 @@ static apr_status_t ssl_filter_io_shutdown(ssl_filter_ctx_t *filter_ctx,
if (abortive) {
shutdown_type = SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN;
type = "abortive";
+ logno = APLOGNO(01998);
+ loglevel = APLOG_INFO;
}
else switch (sslconn->shutdown_type) {
case SSL_SHUTDOWN_TYPE_UNCLEAN:
@@ -974,12 +954,14 @@ static apr_status_t ssl_filter_io_shutdown(ssl_filter_ctx_t *filter_ctx,
(violates the SSL/TLS standard!) */
shutdown_type = SSL_SENT_SHUTDOWN|SSL_RECEIVED_SHUTDOWN;
type = "unclean";
+ logno = APLOGNO(01999);
break;
case SSL_SHUTDOWN_TYPE_ACCURATE:
/* send close notify and wait for clients close notify
(standard compliant, but usually causes connection hangs) */
shutdown_type = 0;
type = "accurate";
+ logno = APLOGNO(02000);
break;
default:
/*
@@ -990,6 +972,7 @@ static apr_status_t ssl_filter_io_shutdown(ssl_filter_ctx_t *filter_ctx,
(standard compliant and safe, so it's the DEFAULT!) */
shutdown_type = SSL_RECEIVED_SHUTDOWN;
type = "standard";
+ logno = APLOGNO(02001);
break;
}
@@ -997,11 +980,12 @@ static apr_status_t ssl_filter_io_shutdown(ssl_filter_ctx_t *filter_ctx,
SSL_smart_shutdown(ssl);
/* and finally log the fact that we've closed the connection */
- if (mySrvFromConn(c)->loglevel >= APLOG_INFO) {
- ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c,
- "Connection closed to child %ld with %s shutdown "
- "(server %s)",
- c->id, type, ssl_util_vhostid(c->pool, mySrvFromConn(c)));
+ if (APLOG_CS_IS_LEVEL(c, mySrvFromConn(c), loglevel)) {
+ ap_log_cserror(APLOG_MARK, loglevel, 0, c, mySrvFromConn(c),
+ "%sConnection closed to child %ld with %s shutdown "
+ "(server %s)",
+ logno, c->id, type,
+ ssl_util_vhostid(c->pool, mySrvFromConn(c)));
}
/* deallocate the SSL connection */
@@ -1017,8 +1001,6 @@ static apr_status_t ssl_filter_io_shutdown(ssl_filter_ctx_t *filter_ctx,
/* prevent any further I/O */
c->aborted = 1;
}
-
- return APR_SUCCESS;
}
static apr_status_t ssl_io_filter_cleanup(void *data)
@@ -1043,7 +1025,10 @@ static apr_status_t ssl_io_filter_cleanup(void *data)
* Adv. if conn_rec * can be accepted is we can hook this function using the
* ap_hook_process_connection hook.
*/
-static int ssl_io_filter_connect(ssl_filter_ctx_t *filter_ctx)
+
+/* Perform the SSL handshake (whether in client or server mode), if
+ * necessary, for the given connection. */
+static apr_status_t ssl_io_filter_handshake(ssl_filter_ctx_t *filter_ctx)
{
conn_rec *c = (conn_rec *)SSL_get_app_data(filter_ctx->pssl);
SSLConnRec *sslconn = myConnConfig(c);
@@ -1060,59 +1045,87 @@ static int ssl_io_filter_connect(ssl_filter_ctx_t *filter_ctx)
server = sslconn->server;
if (sslconn->is_proxy) {
- const char *hostname_note;
-
+#ifndef OPENSSL_NO_TLSEXT
+ apr_ipsubnet_t *ip;
+#endif
+ const char *hostname_note = apr_table_get(c->notes,
+ "proxy-request-hostname");
sc = mySrvConfig(server);
+
+#ifndef OPENSSL_NO_TLSEXT
+ /*
+ * Enable SNI for backend requests. Make sure we don't do it for
+ * pure SSLv3 connections, and also prevent IP addresses
+ * from being included in the SNI extension. (OpenSSL would simply
+ * pass them on, but RFC 6066 is quite clear on this: "Literal
+ * IPv4 and IPv6 addresses are not permitted".)
+ */
+ if (hostname_note &&
+ sc->proxy->protocol != SSL_PROTOCOL_SSLV3 &&
+ apr_ipsubnet_create(&ip, hostname_note, NULL,
+ c->pool) != APR_SUCCESS) {
+ if (SSL_set_tlsext_host_name(filter_ctx->pssl, hostname_note)) {
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, c,
+ "SNI extension for SSL Proxy request set to '%s'",
+ hostname_note);
+ } else {
+ ap_log_cerror(APLOG_MARK, APLOG_WARNING, 0, c, APLOGNO(02002)
+ "Failed to set SNI extension for SSL Proxy "
+ "request to '%s'", hostname_note);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_WARNING, server);
+ }
+ }
+#endif
+
if ((n = SSL_connect(filter_ctx->pssl)) <= 0) {
- ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c,
+ ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c, APLOGNO(02003)
"SSL Proxy connect failed");
- ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, server);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_INFO, server);
/* ensure that the SSL structures etc are freed, etc: */
ssl_filter_io_shutdown(filter_ctx, c, 1);
- apr_table_set(c->notes, "SSL_connect_rv", "err");
- return HTTP_BAD_GATEWAY;
+ apr_table_setn(c->notes, "SSL_connect_rv", "err");
+ return MODSSL_ERROR_BAD_GATEWAY;
}
- if (sc->proxy_ssl_check_peer_expire == SSL_ENABLED_TRUE) {
+ if (sc->proxy_ssl_check_peer_expire != SSL_ENABLED_FALSE) {
cert = SSL_get_peer_certificate(filter_ctx->pssl);
if (!cert
|| (X509_cmp_current_time(
X509_get_notBefore(cert)) >= 0)
|| (X509_cmp_current_time(
X509_get_notAfter(cert)) <= 0)) {
- ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c,
+ ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c, APLOGNO(02004)
"SSL Proxy: Peer certificate is expired");
if (cert) {
X509_free(cert);
}
/* ensure that the SSL structures etc are freed, etc: */
ssl_filter_io_shutdown(filter_ctx, c, 1);
- apr_table_set(c->notes, "SSL_connect_rv", "err");
+ apr_table_setn(c->notes, "SSL_connect_rv", "err");
return HTTP_BAD_GATEWAY;
}
X509_free(cert);
}
- if ((sc->proxy_ssl_check_peer_cn == SSL_ENABLED_TRUE)
- && ((hostname_note =
- apr_table_get(c->notes, "proxy-request-hostname")) != NULL)) {
+ if ((sc->proxy_ssl_check_peer_cn != SSL_ENABLED_FALSE) &&
+ hostname_note) {
const char *hostname;
hostname = ssl_var_lookup(NULL, server, c, NULL,
"SSL_CLIENT_S_DN_CN");
apr_table_unset(c->notes, "proxy-request-hostname");
if (strcasecmp(hostname, hostname_note)) {
- ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c,
+ ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c, APLOGNO(02005)
"SSL Proxy: Peer certificate CN mismatch:"
" Certificate CN: %s Requested hostname: %s",
hostname, hostname_note);
/* ensure that the SSL structures etc are freed, etc: */
ssl_filter_io_shutdown(filter_ctx, c, 1);
- apr_table_set(c->notes, "SSL_connect_rv", "err");
+ apr_table_setn(c->notes, "SSL_connect_rv", "err");
return HTTP_BAD_GATEWAY;
}
}
- apr_table_set(c->notes, "SSL_connect_rv", "ok");
+ apr_table_setn(c->notes, "SSL_connect_rv", "ok");
return APR_SUCCESS;
}
@@ -1130,7 +1143,7 @@ static int ssl_io_filter_connect(ssl_filter_ctx_t *filter_ctx)
* was transferred. That's not a real error and can occur
* sporadically with some clients.
*/
- ap_log_cerror(APLOG_MARK, APLOG_INFO, rc, c,
+ ap_log_cerror(APLOG_MARK, APLOG_INFO, rc, c, APLOGNO(02006)
"SSL handshake stopped: connection was closed");
}
else if (ssl_err == SSL_ERROR_WANT_READ) {
@@ -1140,7 +1153,7 @@ static int ssl_io_filter_connect(ssl_filter_ctx_t *filter_ctx)
* TBD.
*/
outctx->rc = APR_EAGAIN;
- return SSL_ERROR_WANT_READ;
+ return APR_EAGAIN;
}
else if (ERR_GET_LIB(ERR_peek_error()) == ERR_LIB_SSL &&
ERR_GET_REASON(ERR_peek_error()) == SSL_R_HTTP_REQUEST) {
@@ -1150,10 +1163,10 @@ static int ssl_io_filter_connect(ssl_filter_ctx_t *filter_ctx)
* ssl_io_filter_error will disable the ssl filters when it
* sees this status code.
*/
- return HTTP_BAD_REQUEST;
+ return MODSSL_ERROR_HTTP_ON_HTTPS;
}
else if (ssl_err == SSL_ERROR_SYSCALL) {
- ap_log_cerror(APLOG_MARK, APLOG_INFO, rc, c,
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rc, c, APLOGNO(02007)
"SSL handshake interrupted by system "
"[Hint: Stop button pressed in browser?!]");
}
@@ -1161,18 +1174,19 @@ static int ssl_io_filter_connect(ssl_filter_ctx_t *filter_ctx)
/*
* Log SSL errors and any unexpected conditions.
*/
- ap_log_cerror(APLOG_MARK, APLOG_INFO, rc, c,
+ ap_log_cerror(APLOG_MARK, APLOG_INFO, rc, c, APLOGNO(02008)
"SSL library error %d in handshake "
"(server %s)", ssl_err,
ssl_util_vhostid(c->pool, server));
- ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, server);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_INFO, server);
}
if (inctx->rc == APR_SUCCESS) {
inctx->rc = APR_EGENERAL;
}
- return ssl_filter_io_shutdown(filter_ctx, c, 1);
+ ssl_filter_io_shutdown(filter_ctx, c, 1);
+ return inctx->rc;
}
sc = mySrvConfig(sslconn->server);
@@ -1195,24 +1209,25 @@ static int ssl_io_filter_connect(ssl_filter_ctx_t *filter_ctx)
* optional_no_ca doesn't appear to work as advertised
* in 1.x
*/
- ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c,
+ ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c, APLOGNO(02009)
"SSL client authentication failed, "
"accepting certificate based on "
"\"SSLVerifyClient optional_no_ca\" "
"configuration");
- ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, server);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_INFO, server);
}
else {
const char *error = sslconn->verify_error ?
sslconn->verify_error :
X509_verify_cert_error_string(verify_result);
- ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c,
+ ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c, APLOGNO(02010)
"SSL client authentication failed: %s",
error ? error : "unknown");
- ssl_log_ssl_error(APLOG_MARK, APLOG_INFO, server);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_INFO, server);
- return ssl_filter_io_shutdown(filter_ctx, c, 1);
+ ssl_filter_io_shutdown(filter_ctx, c, 1);
+ return APR_ECONNABORTED;
}
}
@@ -1234,94 +1249,16 @@ static int ssl_io_filter_connect(ssl_filter_ctx_t *filter_ctx)
if ((sc->server->auth.verify_mode == SSL_CVERIFY_REQUIRE) &&
!sslconn->client_cert)
{
- ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c,
+ ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c, APLOGNO(02011)
"No acceptable peer certificate available");
- return ssl_filter_io_shutdown(filter_ctx, c, 1);
+ ssl_filter_io_shutdown(filter_ctx, c, 1);
+ return APR_ECONNABORTED;
}
return APR_SUCCESS;
}
-#define SWITCH_STATUS_LINE "HTTP/1.1 101 Switching Protocols"
-#define UPGRADE_HEADER "Upgrade: TLS/1.0, HTTP/1.1"
-#define CONNECTION_HEADER "Connection: Upgrade"
-
-static apr_status_t ssl_io_filter_Upgrade(ap_filter_t *f,
- apr_bucket_brigade *bb)
-{
- const char *upgrade;
- apr_bucket_brigade *upgradebb;
- request_rec *r = f->r;
- SSLConnRec *sslconn;
- apr_status_t rv;
- apr_bucket *b;
- SSL *ssl;
-
- /* Just remove the filter, if it doesn't work the first time, it won't
- * work at all for this request.
- */
- ap_remove_output_filter(f);
-
- /* No need to ensure that this is a server with optional SSL, the filter
- * is only inserted if that is true.
- */
-
- upgrade = apr_table_get(r->headers_in, "Upgrade");
- if (upgrade == NULL
- || strcmp(ap_getword(r->pool, &upgrade, ','), "TLS/1.0")) {
- /* "Upgrade: TLS/1.0, ..." header not found, don't do Upgrade */
- return ap_pass_brigade(f->next, bb);
- }
-
- apr_table_unset(r->headers_out, "Upgrade");
-
- /* Send the interim 101 response. */
- upgradebb = apr_brigade_create(r->pool, f->c->bucket_alloc);
-
- ap_fputstrs(f->next, upgradebb, SWITCH_STATUS_LINE, CRLF,
- UPGRADE_HEADER, CRLF, CONNECTION_HEADER, CRLF, CRLF, NULL);
-
- b = apr_bucket_flush_create(f->c->bucket_alloc);
- APR_BRIGADE_INSERT_TAIL(upgradebb, b);
-
- rv = ap_pass_brigade(f->next, upgradebb);
- if (rv) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
- "could not send interim 101 Upgrade response");
- return AP_FILTER_ERROR;
- }
-
- ssl_init_ssl_connection(f->c);
-
- ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
- "Awaiting re-negotiation handshake");
-
- sslconn = myConnConfig(f->c);
- ssl = sslconn->ssl;
-
- /* XXX: Should replace SSL_set_state with SSL_renegotiate(ssl);
- * However, this causes failures in perl-framework currently,
- * perhaps pre-test if we have already negotiated?
- */
- SSL_set_accept_state(ssl);
- SSL_do_handshake(ssl);
-
- if (SSL_get_state(ssl) != SSL_ST_OK) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "TLS Upgrade handshake failed: "
- "Not accepted by client!?");
-
- return AP_FILTER_ERROR;
- }
-
- /* Now that we have initialized the ssl connection which added the ssl_io_filter,
- pass the brigade off to the connection based output filters so that the
- request can complete encrypted */
- return ap_pass_brigade(f->c->output_filters, bb);
-
-}
-
static apr_status_t ssl_io_filter_input(ap_filter_t *f,
apr_bucket_brigade *bb,
ap_input_mode_t mode,
@@ -1330,8 +1267,8 @@ static apr_status_t ssl_io_filter_input(ap_filter_t *f,
{
apr_status_t status;
bio_filter_in_ctx_t *inctx = f->ctx;
-
- apr_size_t len = sizeof(inctx->buffer);
+ const char *start = inctx->buffer; /* start of block to return */
+ apr_size_t len = sizeof(inctx->buffer); /* length of block to return */
int is_init = (mode == AP_MODE_INIT);
if (f->c->aborted) {
@@ -1357,12 +1294,12 @@ static apr_status_t ssl_io_filter_input(ap_filter_t *f,
inctx->mode = mode;
inctx->block = block;
- /* XXX: we could actually move ssl_io_filter_connect to an
+ /* XXX: we could actually move ssl_io_filter_handshake to an
* ap_hook_process_connection but would still need to call it for
* AP_MODE_INIT for protocols that may upgrade the connection
* rather than have SSLEngine On configured.
*/
- if ((status = ssl_io_filter_connect(inctx->filter_ctx)) != APR_SUCCESS) {
+ if ((status = ssl_io_filter_handshake(inctx->filter_ctx)) != APR_SUCCESS) {
return ssl_io_filter_error(f, bb, status);
}
@@ -1383,7 +1320,25 @@ static apr_status_t ssl_io_filter_input(ap_filter_t *f,
status = ssl_io_input_read(inctx, inctx->buffer, &len);
}
else if (inctx->mode == AP_MODE_GETLINE) {
- status = ssl_io_input_getline(inctx, inctx->buffer, &len);
+ const char *pos;
+
+ /* Satisfy the read directly out of the buffer if possible;
+ * invoking ssl_io_input_getline will mean the entire buffer
+ * is copied once (unnecessarily) for each GETLINE call. */
+ if (inctx->cbuf.length
+ && (pos = memchr(inctx->cbuf.value, APR_ASCII_LF,
+ inctx->cbuf.length)) != NULL) {
+ start = inctx->cbuf.value;
+ len = 1 + pos - start; /* +1 to include LF */
+ /* Buffer contents now consumed. */
+ inctx->cbuf.value += len;
+ inctx->cbuf.length -= len;
+ status = APR_SUCCESS;
+ }
+ else {
+ /* Otherwise fall back to the hard way. */
+ status = ssl_io_input_getline(inctx, inctx->buffer, &len);
+ }
}
else {
/* We have no idea what you are talking about, so return an error. */
@@ -1405,13 +1360,156 @@ static apr_status_t ssl_io_filter_input(ap_filter_t *f,
/* Create a transient bucket out of the decrypted data. */
if (len > 0) {
apr_bucket *bucket =
- apr_bucket_transient_create(inctx->buffer, len, f->c->bucket_alloc);
+ apr_bucket_transient_create(start, len, f->c->bucket_alloc);
APR_BRIGADE_INSERT_TAIL(bb, bucket);
}
return APR_SUCCESS;
}
+
+/* ssl_io_filter_output() produces one SSL/TLS message per bucket
+ * passed down the output filter stack. This results in a high
+ * overhead (network packets) for any output comprising many small
+ * buckets. SSI page applied through the HTTP chunk filter, for
+ * example, may produce many brigades containing small buckets -
+ * [chunk-size CRLF] [chunk-data] [CRLF].
+ *
+ * The coalescing filter merges many small buckets into larger buckets
+ * where possible, allowing the SSL I/O output filter to handle them
+ * more efficiently. */
+
+#define COALESCE_BYTES (2048)
+
+struct coalesce_ctx {
+ char buffer[COALESCE_BYTES];
+ apr_size_t bytes; /* number of bytes of buffer used. */
+};
+
+static apr_status_t ssl_io_filter_coalesce(ap_filter_t *f,
+ apr_bucket_brigade *bb)
+{
+ apr_bucket *e, *last = NULL;
+ apr_size_t bytes = 0;
+ struct coalesce_ctx *ctx = f->ctx;
+ unsigned count = 0;
+
+ /* The brigade consists of zero-or-more small data buckets which
+ * can be coalesced (the prefix), followed by the remainder of the
+ * brigade.
+ *
+ * Find the last bucket - if any - of that prefix. count gives
+ * the number of buckets in the prefix. The "prefix" must contain
+ * only data buckets with known length, and must be of a total
+ * size which fits into the buffer.
+ *
+ * N.B.: The process here could be repeated throughout the brigade
+ * (coalesce any run of consecutive data buckets) but this would
+ * add significant complexity, particularly to memory
+ * management. */
+ for (e = APR_BRIGADE_FIRST(bb);
+ e != APR_BRIGADE_SENTINEL(bb)
+ && !APR_BUCKET_IS_METADATA(e)
+ && e->length != (apr_size_t)-1
+ && e->length < COALESCE_BYTES
+ && (bytes + e->length) < COALESCE_BYTES
+ && (ctx == NULL
+ || bytes + ctx->bytes + e->length < COALESCE_BYTES);
+ e = APR_BUCKET_NEXT(e)) {
+ last = e;
+ if (e->length) count++; /* don't count zero-length buckets */
+ bytes += e->length;
+ }
+
+ /* Coalesce the prefix, if:
+ * a) more than one bucket is found to coalesce, or
+ * b) the brigade contains only a single data bucket, or
+ * c)
+ */
+ if (bytes > 0
+ && (count > 1
+ || (count == 1 && APR_BUCKET_NEXT(last) == APR_BRIGADE_SENTINEL(bb)))) {
+ /* If coalescing some bytes, ensure a context has been
+ * created. */
+ if (!ctx) {
+ f->ctx = ctx = apr_palloc(f->c->pool, sizeof *ctx);
+ ctx->bytes = 0;
+ }
+
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, f->c,
+ "coalesce: have %" APR_SIZE_T_FMT " bytes, "
+ "adding %" APR_SIZE_T_FMT " more", ctx->bytes, bytes);
+
+ /* Iterate through the prefix segment. For non-fatal errors
+ * in this loop it is safe to break out and fall back to the
+ * normal path of sending the buffer + remaining buckets in
+ * brigade. */
+ e = APR_BRIGADE_FIRST(bb);
+ while (e != last) {
+ apr_size_t len;
+ const char *data;
+ apr_bucket *next;
+
+ if (APR_BUCKET_IS_METADATA(e)
+ || e->length == (apr_size_t)-1) {
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, f->c, APLOGNO(02012)
+ "unexpected bucket type during coalesce");
+ break; /* non-fatal error; break out */
+ }
+
+ if (e->length) {
+ apr_status_t rv;
+
+ /* A blocking read should be fine here for a
+ * known-length data bucket, rather than the usual
+ * non-block/flush/block. */
+ rv = apr_bucket_read(e, &data, &len, APR_BLOCK_READ);
+ if (rv) {
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, f->c, APLOGNO(02013)
+ "coalesce failed to read from data bucket");
+ return AP_FILTER_ERROR;
+ }
+
+ /* Be paranoid. */
+ if (len > sizeof ctx->buffer
+ || (len + ctx->bytes > sizeof ctx->buffer)) {
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, f->c, APLOGNO(02014)
+ "unexpected coalesced bucket data length");
+ break; /* non-fatal error; break out */
+ }
+
+ memcpy(ctx->buffer + ctx->bytes, data, len);
+ ctx->bytes += len;
+ }
+
+ next = APR_BUCKET_NEXT(e);
+ apr_bucket_delete(e);
+ e = next;
+ }
+ }
+
+ if (APR_BRIGADE_EMPTY(bb)) {
+ /* If the brigade is now empty, our work here is done. */
+ return APR_SUCCESS;
+ }
+
+ /* If anything remains in the brigade, it must now be passed down
+ * the filter stack, first prepending anything that has been
+ * coalesced. */
+ if (ctx && ctx->bytes) {
+ apr_bucket *e;
+
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, f->c,
+ "coalesce: passing on %" APR_SIZE_T_FMT " bytes", ctx->bytes);
+
+ e = apr_bucket_transient_create(ctx->buffer, ctx->bytes, bb->bucket_alloc);
+ APR_BRIGADE_INSERT_HEAD(bb, e);
+ ctx->bytes = 0; /* buffer now emptied. */
+ }
+
+ return ap_pass_brigade(f->next, bb);
+}
+
static apr_status_t ssl_io_filter_output(ap_filter_t *f,
apr_bucket_brigade *bb)
{
@@ -1441,7 +1539,7 @@ static apr_status_t ssl_io_filter_output(ap_filter_t *f,
inctx->mode = AP_MODE_READBYTES;
inctx->block = APR_BLOCK_READ;
- if ((status = ssl_io_filter_connect(filter_ctx)) != APR_SUCCESS) {
+ if ((status = ssl_io_filter_handshake(filter_ctx)) != APR_SUCCESS) {
return ssl_io_filter_error(f, bb, status);
}
@@ -1478,16 +1576,9 @@ static apr_status_t ssl_io_filter_output(ap_filter_t *f,
}
}
else if (AP_BUCKET_IS_EOC(bucket)) {
- /* The special "EOC" bucket means a shutdown is needed;
- * - turn off buffering in bio_filter_out_write
- * - issue the SSL_shutdown
- */
- filter_ctx->nobuffer = 1;
- status = ssl_filter_io_shutdown(filter_ctx, f->c, 0);
- if (status != APR_SUCCESS) {
- ap_log_cerror(APLOG_MARK, APLOG_INFO, status, f->c,
- "SSL filter error shutting down I/O");
- }
+ /* The EOC bucket indicates connection closure, so SSL
+ * shutdown must now be performed. */
+ ssl_filter_io_shutdown(filter_ctx, f->c, 0);
if ((status = ap_pass_brigade(f->next, bb)) != APR_SUCCESS) {
return status;
}
@@ -1530,7 +1621,6 @@ static apr_status_t ssl_io_filter_output(ap_filter_t *f,
struct modssl_buffer_ctx {
apr_bucket_brigade *bb;
- apr_pool_t *pool;
};
int ssl_io_buffer_fill(request_rec *r, apr_size_t maxlen)
@@ -1545,13 +1635,12 @@ int ssl_io_buffer_fill(request_rec *r, apr_size_t maxlen)
* containing a setaside pool and a brigade which constrain the
* lifetime of the buffered data. */
ctx = apr_palloc(r->pool, sizeof *ctx);
- apr_pool_create(&ctx->pool, r->pool);
- ctx->bb = apr_brigade_create(ctx->pool, c->bucket_alloc);
+ ctx->bb = apr_brigade_create(r->pool, c->bucket_alloc);
/* ... and a temporary brigade. */
tempb = apr_brigade_create(r->pool, c->bucket_alloc);
- ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, "filling buffer, max size "
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, c, "filling buffer, max size "
"%" APR_SIZE_T_FMT " bytes", maxlen);
do {
@@ -1566,7 +1655,7 @@ int ssl_io_buffer_fill(request_rec *r, apr_size_t maxlen)
rv = ap_get_brigade(r->proto_input_filters, tempb, AP_MODE_READBYTES,
APR_BLOCK_READ, 8192);
if (rv) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(02015)
"could not read request body for SSL buffer");
return HTTP_INTERNAL_SERVER_ERROR;
}
@@ -1585,16 +1674,16 @@ int ssl_io_buffer_fill(request_rec *r, apr_size_t maxlen)
} else if (!APR_BUCKET_IS_METADATA(e)) {
rv = apr_bucket_read(e, &data, &len, APR_BLOCK_READ);
if (rv != APR_SUCCESS) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(02016)
"could not read bucket for SSL buffer");
return HTTP_INTERNAL_SERVER_ERROR;
}
total += len;
}
- rv = apr_bucket_setaside(e, ctx->pool);
+ rv = apr_bucket_setaside(e, r->pool);
if (rv != APR_SUCCESS) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r, APLOGNO(02017)
"could not setaside bucket for SSL buffer");
return HTTP_INTERNAL_SERVER_ERROR;
}
@@ -1603,14 +1692,14 @@ int ssl_io_buffer_fill(request_rec *r, apr_size_t maxlen)
APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
}
- ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, c,
"total of %" APR_OFF_T_FMT " bytes in buffer, eos=%d",
total, eos);
/* Fail if this exceeds the maximum buffer size. */
if (total > maxlen) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "request body exceeds maximum size (%" APR_SIZE_T_FMT
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02018)
+ "request body exceeds maximum size (%" APR_SIZE_T_FMT
") for SSL buffer", maxlen);
return HTTP_REQUEST_ENTITY_TOO_LARGE;
}
@@ -1621,7 +1710,7 @@ int ssl_io_buffer_fill(request_rec *r, apr_size_t maxlen)
/* After consuming all protocol-level input, remove all protocol-level
* filters. It should strictly only be necessary to remove filters
- * at exactly ftype == AP_FTYPE_PROTOCOL, since this filter will
+ * at exactly ftype == AP_FTYPE_PROTOCOL, since this filter will
* precede all > AP_FTYPE_PROTOCOL anyway. */
while (r->proto_input_filters->frec->ftype < AP_FTYPE_CONNECTION) {
ap_remove_input_filter(r->proto_input_filters);
@@ -1647,7 +1736,7 @@ static apr_status_t ssl_io_filter_buffer(ap_filter_t *f,
struct modssl_buffer_ctx *ctx = f->ctx;
apr_status_t rv;
- ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, f->c,
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, f->c,
"read from buffered SSL brigade, mode %d, "
"%" APR_OFF_T_FMT " bytes",
mode, bytes);
@@ -1675,7 +1764,7 @@ static apr_status_t ssl_io_filter_buffer(ap_filter_t *f,
/* Partition the buffered brigade. */
rv = apr_brigade_partition(ctx->bb, bytes, &e);
if (rv && rv != APR_INCOMPLETE) {
- ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, f->c,
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, f->c, APLOGNO(02019)
"could not partition buffered SSL brigade");
ap_remove_input_filter(f);
return rv;
@@ -1705,7 +1794,7 @@ static apr_status_t ssl_io_filter_buffer(ap_filter_t *f,
rv = apr_brigade_split_line(bb, ctx->bb, block, bytes);
if (rv) {
- ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, f->c,
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, f->c, APLOGNO(02020)
"could not split line from buffered SSL brigade");
ap_remove_input_filter(f);
return rv;
@@ -1722,7 +1811,7 @@ static apr_status_t ssl_io_filter_buffer(ap_filter_t *f,
APR_BRIGADE_INSERT_TAIL(bb, e);
}
- ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, f->c,
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE4, 0, f->c,
"buffered SSL brigade exhausted");
/* Note that the filter must *not* be removed here; it may be
* invoked again, see comment above. */
@@ -1731,14 +1820,17 @@ static apr_status_t ssl_io_filter_buffer(ap_filter_t *f,
return APR_SUCCESS;
}
+/* The request_rec pointer is passed in here only to ensure that the
+ * filter chain is modified correctly when doing a TLS upgrade. It
+ * must *not* be used otherwise. */
static void ssl_io_input_add_filter(ssl_filter_ctx_t *filter_ctx, conn_rec *c,
- SSL *ssl)
+ request_rec *r, SSL *ssl)
{
bio_filter_in_ctx_t *inctx;
inctx = apr_palloc(c->pool, sizeof(*inctx));
- filter_ctx->pInputFilter = ap_add_input_filter(ssl_io_filter, inctx, NULL, c);
+ filter_ctx->pInputFilter = ap_add_input_filter(ssl_io_filter, inctx, r, c);
filter_ctx->pbioRead = BIO_new(&bio_filter_in_method);
filter_ctx->pbioRead->ptr = (void *)inctx;
@@ -1755,7 +1847,10 @@ static void ssl_io_input_add_filter(ssl_filter_ctx_t *filter_ctx, conn_rec *c,
inctx->filter_ctx = filter_ctx;
}
-void ssl_io_filter_init(conn_rec *c, SSL *ssl)
+/* The request_rec pointer is passed in here only to ensure that the
+ * filter chain is modified correctly when doing a TLS upgrade. It
+ * must *not* be used otherwise. */
+void ssl_io_filter_init(conn_rec *c, request_rec *r, SSL *ssl)
{
ssl_filter_ctx_t *filter_ctx;
@@ -1763,17 +1858,18 @@ void ssl_io_filter_init(conn_rec *c, SSL *ssl)
filter_ctx->config = myConnConfig(c);
- filter_ctx->nobuffer = 0;
+ ap_add_output_filter(ssl_io_coalesce, NULL, r, c);
+
filter_ctx->pOutputFilter = ap_add_output_filter(ssl_io_filter,
- filter_ctx, NULL, c);
+ filter_ctx, r, c);
filter_ctx->pbioWrite = BIO_new(&bio_filter_out_method);
filter_ctx->pbioWrite->ptr = (void *)bio_filter_out_ctx_new(filter_ctx, c);
/* We insert a clogging input filter. Let the core know. */
c->clogging_input_filters = 1;
-
- ssl_io_input_add_filter(filter_ctx, c, ssl);
+
+ ssl_io_input_add_filter(filter_ctx, c, r, ssl);
SSL_set_bio(ssl, filter_ctx->pbioRead, filter_ctx->pbioWrite);
filter_ctx->pssl = ssl;
@@ -1781,7 +1877,7 @@ void ssl_io_filter_init(conn_rec *c, SSL *ssl)
apr_pool_cleanup_register(c->pool, (void*)filter_ctx,
ssl_io_filter_cleanup, apr_pool_cleanup_null);
- if (c->base_server->loglevel >= APLOG_DEBUG) {
+ if (APLOG_CS_IS_LEVEL(c, mySrvFromConn(c), APLOG_TRACE4)) {
BIO_set_callback(SSL_get_rbio(ssl), ssl_io_data_cb);
BIO_set_callback_arg(SSL_get_rbio(ssl), (void *)ssl);
}
@@ -1791,12 +1887,8 @@ void ssl_io_filter_init(conn_rec *c, SSL *ssl)
void ssl_io_filter_register(apr_pool_t *p)
{
- /* This filter MUST be after the HTTP_HEADER filter, but it also must be
- * a resource-level filter so it has the request_rec.
- */
- ap_register_output_filter ("UPGRADE_FILTER", ssl_io_filter_Upgrade, NULL, AP_FTYPE_PROTOCOL + 5);
-
ap_register_input_filter (ssl_io_filter, ssl_io_filter_input, NULL, AP_FTYPE_CONNECTION + 5);
+ ap_register_output_filter (ssl_io_coalesce, ssl_io_filter_coalesce, NULL, AP_FTYPE_CONNECTION + 4);
ap_register_output_filter (ssl_io_filter, ssl_io_filter_output, NULL, AP_FTYPE_CONNECTION + 5);
ap_register_input_filter (ssl_io_buffer, ssl_io_filter_buffer, NULL, AP_FTYPE_PROTOCOL);
@@ -1813,7 +1905,7 @@ void ssl_io_filter_register(apr_pool_t *p)
#define DUMP_WIDTH 16
static void ssl_io_data_dump(server_rec *srvr,
- MODSSL_BIO_CB_ARG_TYPE *s,
+ const char *s,
long len)
{
char buf[256];
@@ -1827,19 +1919,19 @@ static void ssl_io_data_dump(server_rec *srvr,
rows = (len / DUMP_WIDTH);
if ((rows * DUMP_WIDTH) < len)
rows++;
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, srvr,
+ ap_log_error(APLOG_MARK, APLOG_TRACE7, 0, srvr,
"+-------------------------------------------------------------------------+");
for(i = 0 ; i< rows; i++) {
#if APR_CHARSET_EBCDIC
char ebcdic_text[DUMP_WIDTH];
- /* Determine how many bytes we are going to process in this row. */
j = DUMP_WIDTH;
if ((i * DUMP_WIDTH + j) > len)
j = len % DUMP_WIDTH;
- if (j == 0) j = DUMP_WIDTH;
- memcpy(ebcdic_text, (char *)(s) + i * DUMP_WIDTH, j);
+ if (j == 0)
+ j = DUMP_WIDTH;
+ memcpy(ebcdic_text,(char *)(s) + i * DUMP_WIDTH, j);
ap_xlate_proto_from_ascii(ebcdic_text, j);
-#endif
+#endif /* APR_CHARSET_EBCDIC */
apr_snprintf(tmp, sizeof(tmp), "| %04x: ", i * DUMP_WIDTH);
apr_cpystrn(buf, tmp, sizeof(buf));
for (j = 0; j < DUMP_WIDTH; j++) {
@@ -1857,28 +1949,28 @@ static void ssl_io_data_dump(server_rec *srvr,
apr_cpystrn(buf+strlen(buf), " ", sizeof(buf)-strlen(buf));
else {
ch = ((unsigned char)*((char *)(s) + i * DUMP_WIDTH + j)) & 0xff;
-#if APR_CHARSET_EBCDIC
- apr_snprintf(tmp, sizeof(tmp), "%c", ((ch >= 0x20 /*' '*/) && (ch <= 0x7e /*'~'*/)) ? ebcdic_text[j] : '.');
-#else
+#if APR_CHARSET_EBCDIC
+ apr_snprintf(tmp, sizeof(tmp), "%c", (ch >= 0x20 && ch <= 0x7F) ? ebcdic_text[j] : '.');
+#else /* APR_CHARSET_EBCDIC */
apr_snprintf(tmp, sizeof(tmp), "%c", ((ch >= ' ') && (ch <= '~')) ? ch : '.');
-#endif
+#endif /* APR_CHARSET_EBCDIC */
apr_cpystrn(buf+strlen(buf), tmp, sizeof(buf)-strlen(buf));
}
}
apr_cpystrn(buf+strlen(buf), " |", sizeof(buf)-strlen(buf));
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, srvr,
+ ap_log_error(APLOG_MARK, APLOG_TRACE7, 0, srvr,
"%s", buf);
}
if (trunc > 0)
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, srvr,
+ ap_log_error(APLOG_MARK, APLOG_TRACE7, 0, srvr,
"| %04ld - <SPACES/NULS>", len + trunc);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, srvr,
+ ap_log_error(APLOG_MARK, APLOG_TRACE7, 0, srvr,
"+-------------------------------------------------------------------------+");
return;
}
long ssl_io_data_cb(BIO *bio, int cmd,
- MODSSL_BIO_CB_ARG_TYPE *argp,
+ const char *argp,
int argi, long argl, long rc)
{
SSL *ssl;
@@ -1894,18 +1986,18 @@ long ssl_io_data_cb(BIO *bio, int cmd,
if ( cmd == (BIO_CB_WRITE|BIO_CB_RETURN)
|| cmd == (BIO_CB_READ |BIO_CB_RETURN) ) {
if (rc >= 0) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ ap_log_cserror(APLOG_MARK, APLOG_TRACE4, 0, c, s,
"%s: %s %ld/%d bytes %s BIO#%pp [mem: %pp] %s",
SSL_LIBRARY_NAME,
(cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "write" : "read"),
rc, argi, (cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "to" : "from"),
bio, argp,
(argp != NULL ? "(BIO dump follows)" : "(Oops, no memory buffer?)"));
- if (argp != NULL)
+ if ((argp != NULL) && APLOG_CS_IS_LEVEL(c, s, APLOG_TRACE7))
ssl_io_data_dump(s, argp, rc);
}
else {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ ap_log_cserror(APLOG_MARK, APLOG_TRACE4, 0, c, s,
"%s: I/O error, %d bytes expected to %s on BIO#%pp [mem: %pp]",
SSL_LIBRARY_NAME, argi,
(cmd == (BIO_CB_WRITE|BIO_CB_RETURN) ? "write" : "read"),
diff --git a/modules/ssl/ssl_engine_kernel.c b/modules/ssl/ssl_engine_kernel.c
index 33f97bd9..a4703933 100644
--- a/modules/ssl/ssl_engine_kernel.c
+++ b/modules/ssl/ssl_engine_kernel.c
@@ -29,32 +29,85 @@
time I was too famous.''
-- Unknown */
#include "ssl_private.h"
+#include "util_md5.h"
static void ssl_configure_env(request_rec *r, SSLConnRec *sslconn);
#ifndef OPENSSL_NO_TLSEXT
static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s);
#endif
+#define SWITCH_STATUS_LINE "HTTP/1.1 101 Switching Protocols"
+#define UPGRADE_HEADER "Upgrade: TLS/1.0, HTTP/1.1"
+#define CONNECTION_HEADER "Connection: Upgrade"
+
+/* Perform an upgrade-to-TLS for the given request, per RFC 2817. */
+static apr_status_t upgrade_connection(request_rec *r)
+{
+ struct conn_rec *conn = r->connection;
+ apr_bucket_brigade *bb;
+ SSLConnRec *sslconn;
+ apr_status_t rv;
+ SSL *ssl;
+
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02028)
+ "upgrading connection to TLS");
+
+ bb = apr_brigade_create(r->pool, conn->bucket_alloc);
+
+ rv = ap_fputstrs(conn->output_filters, bb, SWITCH_STATUS_LINE, CRLF,
+ UPGRADE_HEADER, CRLF, CONNECTION_HEADER, CRLF, CRLF, NULL);
+ if (rv == APR_SUCCESS) {
+ APR_BRIGADE_INSERT_TAIL(bb,
+ apr_bucket_flush_create(conn->bucket_alloc));
+ rv = ap_pass_brigade(conn->output_filters, bb);
+ }
+
+ if (rv) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02029)
+ "failed to send 101 interim response for connection "
+ "upgrade");
+ return rv;
+ }
+
+ ssl_init_ssl_connection(conn, r);
+
+ sslconn = myConnConfig(conn);
+ ssl = sslconn->ssl;
+
+ /* Perform initial SSL handshake. */
+ SSL_set_accept_state(ssl);
+ SSL_do_handshake(ssl);
+
+ if (SSL_get_state(ssl) != SSL_ST_OK) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02030)
+ "TLS upgrade handshake failed: not accepted by client!?");
+
+ return APR_ECONNABORTED;
+ }
+
+ return APR_SUCCESS;
+}
+
/* Perform a speculative (and non-blocking) read from the connection
* filters for the given request, to determine whether there is any
* pending data to read. Return non-zero if there is, else zero. */
-static int has_buffered_data(request_rec *r)
+static int has_buffered_data(request_rec *r)
{
apr_bucket_brigade *bb;
apr_off_t len;
apr_status_t rv;
int result;
-
+
bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
-
+
rv = ap_get_brigade(r->connection->input_filters, bb, AP_MODE_SPECULATIVE,
- APR_NONBLOCK_READ, 1);
+ APR_NONBLOCK_READ, 1);
result = rv == APR_SUCCESS
&& apr_brigade_length(bb, 1, &len) == APR_SUCCESS
&& len > 0;
-
+
apr_brigade_destroy(bb);
-
+
return result;
}
@@ -63,12 +116,26 @@ static int has_buffered_data(request_rec *r)
*/
int ssl_hook_ReadReq(request_rec *r)
{
- SSLConnRec *sslconn = myConnConfig(r->connection);
+ SSLSrvConfigRec *sc = mySrvConfig(r->server);
+ SSLConnRec *sslconn;
+ const char *upgrade;
#ifndef OPENSSL_NO_TLSEXT
const char *servername;
#endif
SSL *ssl;
+ /* Perform TLS upgrade here if "SSLEngine optional" is configured,
+ * SSL is not already set up for this connection, and the client
+ * has sent a suitable Upgrade header. */
+ if (sc->enabled == SSL_ENABLED_OPTIONAL && !myConnConfig(r->connection)
+ && (upgrade = apr_table_get(r->headers_in, "Upgrade")) != NULL
+ && ap_find_token(r->pool, upgrade, "TLS/1.0")) {
+ if (upgrade_connection(r)) {
+ return HTTP_INTERNAL_SERVER_ERROR;
+ }
+ }
+
+ sslconn = myConnConfig(r->connection);
if (!sslconn) {
return DECLINED;
}
@@ -85,7 +152,7 @@ int ssl_hook_ReadReq(request_rec *r)
thisurl = ap_escape_html(r->pool,
apr_psprintf(r->pool, "https://%s%s/",
- ap_get_server_name(r),
+ ap_get_server_name_for_url(r),
thisport));
errmsg = apr_psprintf(r->pool,
@@ -127,7 +194,7 @@ int ssl_hook_ReadReq(request_rec *r)
* with either no hostname or a different hostname.
*/
if (!r->hostname) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, APLOGNO(02031)
"Hostname %s provided via SNI, but no hostname"
" provided in HTTP request", servername);
return HTTP_BAD_REQUEST;
@@ -136,15 +203,14 @@ int ssl_hook_ReadReq(request_rec *r)
if (rv != APR_SUCCESS || scope_id) {
return HTTP_BAD_REQUEST;
}
- if (strcmp(host, servername)) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
+ if (strcasecmp(host, servername)) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, APLOGNO(02032)
"Hostname %s provided via SNI and hostname %s provided"
" via HTTP are different", servername, host);
return HTTP_BAD_REQUEST;
}
}
- else if ((((mySrvConfig(r->server))->strict_sni_vhost_check
- == SSL_ENABLED_TRUE)
+ else if (((sc->strict_sni_vhost_check == SSL_ENABLED_TRUE)
|| (mySrvConfig(sslconn->server))->strict_sni_vhost_check
== SSL_ENABLED_TRUE)
&& r->connection->vhost_lookup_data) {
@@ -155,7 +221,7 @@ int ssl_hook_ReadReq(request_rec *r)
* server config we used for handshaking or in our current server.
* This should avoid insecure configuration by accident.
*/
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server, APLOGNO(02033)
"No hostname was provided via SNI for a name based"
" virtual host");
return HTTP_FORBIDDEN;
@@ -166,8 +232,8 @@ int ssl_hook_ReadReq(request_rec *r)
/*
* Log information about incoming HTTPS requests
*/
- if (r->server->loglevel >= APLOG_INFO && ap_is_initial_req(r)) {
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
+ if (APLOGrinfo(r) && ap_is_initial_req(r)) {
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02034)
"%s HTTPS request received for child %ld (server %s)",
(r->connection->keepalives <= 0 ?
"Initial (No.1)" :
@@ -237,7 +303,6 @@ int ssl_hook_Access(request_rec *r)
SSL_CTX *ctx = NULL;
apr_array_header_t *requires;
ssl_require_t *ssl_requires;
- char *cp;
int ok, i;
BOOL renegotiate = FALSE, renegotiate_quick = FALSE;
X509 *cert;
@@ -266,7 +331,7 @@ int ssl_hook_Access(request_rec *r)
return HTTP_UPGRADE_REQUIRED;
}
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02219)
"access to %s failed, reason: %s",
r->filename, "SSL connection required");
@@ -343,13 +408,13 @@ int ssl_hook_Access(request_rec *r)
/* configure new state */
if ((dc->szCipherSuite || sc->server->auth.cipher_suite) &&
- !modssl_set_cipher_list(ssl, dc->szCipherSuite ?
- dc->szCipherSuite :
- sc->server->auth.cipher_suite)) {
- ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
+ !SSL_set_cipher_list(ssl, dc->szCipherSuite ?
+ dc->szCipherSuite :
+ sc->server->auth.cipher_suite)) {
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02253)
"Unable to reconfigure (per-directory) "
"permitted SSL ciphers");
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, r->server);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, r->server);
if (cipher_list_old) {
sk_SSL_CIPHER_free(cipher_list_old);
@@ -418,7 +483,7 @@ int ssl_hook_Access(request_rec *r)
}
#endif
/* tracing */
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02220)
"Reconfigured cipher suite will force renegotiation");
}
}
@@ -435,7 +500,7 @@ int ssl_hook_Access(request_rec *r)
* currently active/remembered verify depth (because this means more
* restriction on the certificate chain).
*/
- n = sslconn->verify_depth ?
+ n = (sslconn->verify_depth != UNSET) ?
sslconn->verify_depth :
(mySrvConfig(handshakeserver))->server->auth.verify_depth;
/* determine the new depth */
@@ -443,7 +508,7 @@ int ssl_hook_Access(request_rec *r)
dc->nVerifyDepth : sc->server->auth.verify_depth;
if (sslconn->verify_depth < n) {
renegotiate = TRUE;
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02254)
"Reduced client verification depth will force "
"renegotiation");
}
@@ -459,7 +524,7 @@ int ssl_hook_Access(request_rec *r)
* Additionally the following optimization is possible here: When the
* currently active verify type is "none" but a client certificate is
* already known/present, it's enough to manually force a client
- * verification but at least skip the I/O-intensive renegotation
+ * verification but at least skip the I/O-intensive renegotiation
* handshake.
*/
if ((dc->nVerifyClient != SSL_CVERIFY_UNSET) ||
@@ -482,7 +547,7 @@ int ssl_hook_Access(request_rec *r)
verify |= SSL_VERIFY_PEER;
}
- modssl_set_verify(ssl, verify, ssl_callback_SSLVerify);
+ SSL_set_verify(ssl, verify, ssl_callback_SSLVerify);
SSL_set_verify_result(ssl, X509_V_OK);
/* determine whether we've to force a renegotiation */
@@ -507,7 +572,7 @@ int ssl_hook_Access(request_rec *r)
X509_free(peercert);
}
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02255)
"Changed client verification type will force "
"%srenegotiation",
renegotiate_quick ? "quick " : "");
@@ -537,12 +602,12 @@ int ssl_hook_Access(request_rec *r)
if (MODSSL_CFG_CA_NE(ca_cert_file, sc, hssc) ||
MODSSL_CFG_CA_NE(ca_cert_path, sc, hssc)) {
if (verify & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) {
- ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02256)
"Non-default virtual host with SSLVerify set to "
"'require' and VirtualHost-specific CA certificate "
"list is only available to clients with TLS server "
"name indication (SNI) support");
- modssl_set_verify(ssl, verify_old, NULL);
+ SSL_set_verify(ssl, verify_old, NULL);
return HTTP_FORBIDDEN;
} else
/* let it pass, possibly with an "incorrect" peer cert,
@@ -554,67 +619,6 @@ int ssl_hook_Access(request_rec *r)
}
}
- /*
- * override SSLCACertificateFile & SSLCACertificatePath
- * This is only enabled if the SSL_set_cert_store() function
- * is available in the ssl library. the 1.x based mod_ssl
- * used SSL_CTX_set_cert_store which is not thread safe.
- */
-
-#ifdef HAVE_SSL_SET_CERT_STORE
- /*
- * check if per-dir and per-server config field are not the same.
- * if f is defined in per-dir and not defined in per-server
- * or f is defined in both but not the equal ...
- */
-#define MODSSL_CFG_NE(f) \
- (dc->f && (!sc->f || (sc->f && strNE(dc->f, sc->f))))
-
-#define MODSSL_CFG_CA(f) \
- (dc->f ? dc->f : sc->f)
-
- if (MODSSL_CFG_NE(szCACertificateFile) ||
- MODSSL_CFG_NE(szCACertificatePath))
- {
- STACK_OF(X509_NAME) *ca_list;
- const char *ca_file = MODSSL_CFG_CA(szCACertificateFile);
- const char *ca_path = MODSSL_CFG_CA(szCACertificatePath);
-
- cert_store = X509_STORE_new();
-
- if (!X509_STORE_load_locations(cert_store, ca_file, ca_path)) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "Unable to reconfigure verify locations "
- "for client authentication");
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, r->server);
-
- X509_STORE_free(cert_store);
-
- return HTTP_FORBIDDEN;
- }
-
- /* SSL_free will free cert_store */
- SSL_set_cert_store(ssl, cert_store);
-
- if (!(ca_list = ssl_init_FindCAList(r->server, r->pool,
- ca_file, ca_path)))
- {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
- "Unable to determine list of available "
- "CA certificates for client authentication");
-
- return HTTP_FORBIDDEN;
- }
-
- SSL_set_client_CA_list(ssl, ca_list);
- renegotiate = TRUE;
-
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
- "Changed client verification locations will force "
- "renegotiation");
- }
-#endif /* HAVE_SSL_SET_CERT_STORE */
-
/* If a renegotiation is now required for this location, and the
* request includes a message body (and the client has not
* requested a "100 Continue" response), then the client will be
@@ -648,7 +652,7 @@ int ssl_hook_Access(request_rec *r)
}
if (rv) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02257)
"could not buffer message body to allow "
"SSL renegotiation to proceed");
return rv;
@@ -660,7 +664,7 @@ int ssl_hook_Access(request_rec *r)
*/
if (renegotiate) {
/*
- * Now we force the SSL renegotation by sending the Hello Request
+ * Now we force the SSL renegotiation by sending the Hello Request
* message to the client. Here we have to do a workaround: Actually
* OpenSSL returns immediately after sending the Hello Request (the
* intent AFAIK is because the SSL/TLS protocol says it's not a must
@@ -670,14 +674,14 @@ int ssl_hook_Access(request_rec *r)
* here because it resets too much of the connection. So we set the
* state explicitly and continue the handshake manually.
*/
- ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02221)
"Requesting connection re-negotiation");
if (renegotiate_quick) {
STACK_OF(X509) *cert_stack;
/* perform just a manual re-verification of the peer */
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02258)
"Performing quick renegotiation: "
"just re-verifying the peer");
@@ -692,11 +696,11 @@ int ssl_hook_Access(request_rec *r)
* we put it back here for the purpose of quick_renegotiation.
*/
cert_stack = sk_X509_new_null();
- sk_X509_push(cert_stack, MODSSL_PCHAR_CAST cert);
+ sk_X509_push(cert_stack, cert);
}
if (!cert_stack || (sk_X509_num(cert_stack) == 0)) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02222)
"Cannot find peer certificate chain");
return HTTP_FORBIDDEN;
@@ -705,7 +709,7 @@ int ssl_hook_Access(request_rec *r)
if (!(cert_store ||
(cert_store = SSL_CTX_get_cert_store(ctx))))
{
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02223)
"Cannot find certificate storage");
return HTTP_FORBIDDEN;
@@ -726,10 +730,10 @@ int ssl_hook_Access(request_rec *r)
SSL_get_ex_data_X509_STORE_CTX_idx(),
(char *)ssl);
- if (!modssl_X509_verify_cert(&cert_store_ctx)) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ if (!X509_verify_cert(&cert_store_ctx)) {
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02224)
"Re-negotiation verification step failed");
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, r->server);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, r->server);
}
SSL_set_verify_result(ssl, cert_store_ctx.error);
@@ -753,7 +757,7 @@ int ssl_hook_Access(request_rec *r)
* discarded. Legimately pipelined HTTP requests will be
* retried anyway with this approach. */
if (has_buffered_data(r)) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02259)
"insecure SSL re-negotiation required, but "
"a pipelined request is present; keepalive "
"disabled");
@@ -761,11 +765,11 @@ int ssl_hook_Access(request_rec *r)
}
/* Perform a full renegotiation. */
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO(02260)
"Performing full renegotiation: complete handshake "
"protocol (%s support secure renegotiation)",
#if defined(SSL_get_secure_renegotiation_support)
- SSL_get_secure_renegotiation_support(ssl) ?
+ SSL_get_secure_renegotiation_support(ssl) ?
"client does" : "client does not"
#else
"server does not"
@@ -779,37 +783,37 @@ int ssl_hook_Access(request_rec *r)
/* Toggle the renegotiation state to allow the new
* handshake to proceed. */
sslconn->reneg_state = RENEG_ALLOW;
-
+
SSL_renegotiate(ssl);
SSL_do_handshake(ssl);
if (SSL_get_state(ssl) != SSL_ST_OK) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02225)
"Re-negotiation request failed");
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, r->server);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, r->server);
- r->connection->aborted = 1;
+ r->connection->keepalive = AP_CONN_CLOSE;
return HTTP_FORBIDDEN;
}
- ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02226)
"Awaiting re-negotiation handshake");
- /* XXX: Should replace SSL_set_state with SSL_renegotiate(ssl);
+ /* XXX: Should replace setting ssl->state with SSL_renegotiate(ssl);
* However, this causes failures in perl-framework currently,
* perhaps pre-test if we have already negotiated?
*/
- SSL_set_state(ssl, SSL_ST_ACCEPT);
+ ssl->state = SSL_ST_ACCEPT;
SSL_do_handshake(ssl);
sslconn->reneg_state = RENEG_REJECT;
if (SSL_get_state(ssl) != SSL_ST_OK) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02261)
"Re-negotiation handshake failed: "
"Not accepted by client!?");
- r->connection->aborted = 1;
+ r->connection->keepalive = AP_CONN_CLOSE;
return HTTP_FORBIDDEN;
}
}
@@ -834,7 +838,7 @@ int ssl_hook_Access(request_rec *r)
(sc->server->auth.verify_mode == SSL_CVERIFY_REQUIRE));
if (do_verify && (SSL_get_verify_result(ssl) != X509_V_OK)) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02262)
"Re-negotiation handshake failed: "
"Client verification failed");
@@ -843,7 +847,7 @@ int ssl_hook_Access(request_rec *r)
if (do_verify) {
if ((peercert = SSL_get_peer_certificate(ssl)) == NULL) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02263)
"Re-negotiation handshake failed: "
"Client certificate missing");
@@ -860,7 +864,7 @@ int ssl_hook_Access(request_rec *r)
if (cipher_list) {
cipher = SSL_get_current_cipher(ssl);
if (sk_SSL_CIPHER_find(cipher_list, cipher) < 0) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02264)
"SSL cipher suite not renegotiated: "
"access to %s denied using cipher %s",
r->filename,
@@ -882,6 +886,9 @@ int ssl_hook_Access(request_rec *r)
r, (char *)dc->szUserName);
if (val && val[0])
r->user = val;
+ else
+ ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, APLOGNO(02227)
+ "Failed to set r->user to '%s'", dc->szUserName);
}
/*
@@ -892,17 +899,14 @@ int ssl_hook_Access(request_rec *r)
for (i = 0; i < requires->nelts; i++) {
ssl_require_t *req = &ssl_requires[i];
- ok = ssl_expr_exec(r, req->mpExpr);
+ const char *errstring;
+ ok = ap_expr_exec(r, req->mpExpr, &errstring);
if (ok < 0) {
- cp = apr_psprintf(r->pool,
- "Failed to execute "
- "SSL requirement expression: %s",
- ssl_expr_get_error());
-
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
- "access to %s failed, reason: %s",
- r->filename, cp);
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02265)
+ "access to %s failed, reason: Failed to execute "
+ "SSL requirement expression: %s",
+ r->filename, errstring);
/* remember forbidden access for strict require option */
apr_table_setn(r->notes, "ssl-access-forbidden", "1");
@@ -911,19 +915,18 @@ int ssl_hook_Access(request_rec *r)
}
if (ok != 1) {
- ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02266)
"Access to %s denied for %s "
"(requirement expression not fulfilled)",
- r->filename, r->connection->remote_ip);
+ r->filename, r->useragent_ip);
- ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02228)
"Failed expression: %s", req->cpExpr);
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02229)
"access to %s failed, reason: %s",
r->filename,
- "SSL requirement expression not fulfilled "
- "(see SSL logfile for more details)");
+ "SSL requirement expression not fulfilled");
/* remember forbidden access for strict require option */
apr_table_setn(r->notes, "ssl-access-forbidden", "1");
@@ -994,7 +997,7 @@ int ssl_hook_UserCheck(request_rec *r)
password = auth_line;
if ((username[0] == '/') && strEQ(password, "password")) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, APLOGNO(02035)
"Encountered FakeBasicAuth spoof: %s", username);
return HTTP_FORBIDDEN;
}
@@ -1019,7 +1022,7 @@ int ssl_hook_UserCheck(request_rec *r)
X509_NAME *name = X509_get_subject_name(sslconn->client_cert);
char *cp = X509_NAME_oneline(name, NULL, 0);
sslconn->client_dn = apr_pstrdup(r->connection->pool, cp);
- modssl_free(cp);
+ OPENSSL_free(cp);
}
clientdn = (char *)sslconn->client_dn;
@@ -1040,9 +1043,9 @@ int ssl_hook_UserCheck(request_rec *r)
apr_pstrcat(r->pool, clientdn,
":password", NULL)),
NULL);
- apr_table_set(r->headers_in, "Authorization", auth_line);
+ apr_table_setn(r->headers_in, "Authorization", auth_line);
- ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
+ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, APLOGNO(02036)
"Faking HTTP Basic Auth header: \"Authorization: %s\"",
auth_line);
@@ -1100,6 +1103,7 @@ static const char *ssl_hook_Fixup_vars[] = {
"SSL_SERVER_A_KEY",
"SSL_SERVER_A_SIG",
"SSL_SESSION_ID",
+ "SSL_SESSION_RESUMED",
NULL
};
@@ -1117,8 +1121,13 @@ int ssl_hook_Fixup(request_rec *r)
SSL *ssl;
int i;
- if (sc->enabled == SSL_ENABLED_OPTIONAL && !(sslconn && sslconn->ssl)) {
+ /* If "SSLEngine optional" is configured, this is not an SSL
+ * connection, and this isn't a subrequest, send an Upgrade
+ * response header. */
+ if (sc->enabled == SSL_ENABLED_OPTIONAL && !(sslconn && sslconn->ssl)
+ && !r->main) {
apr_table_setn(r->headers_out, "Upgrade", "TLS/1.0, HTTP/1.1");
+ apr_table_mergen(r->headers_out, "Connection", "upgrade");
}
/*
@@ -1182,7 +1191,7 @@ int ssl_hook_Fixup(request_rec *r)
#ifdef SSL_get_secure_renegotiation_support
- apr_table_setn(r->notes, "ssl-secure-reneg",
+ apr_table_setn(r->notes, "ssl-secure-reneg",
SSL_get_secure_renegotiation_support(ssl) ? "1" : "0");
#endif
@@ -1191,6 +1200,87 @@ int ssl_hook_Fixup(request_rec *r)
/* _________________________________________________________________
**
+** Authz providers for use with mod_authz_core
+** _________________________________________________________________
+*/
+
+static authz_status ssl_authz_require_ssl_check(request_rec *r,
+ const char *require_line,
+ const void *parsed)
+{
+ SSLConnRec *sslconn = myConnConfig(r->connection);
+ SSL *ssl = sslconn ? sslconn->ssl : NULL;
+
+ if (ssl)
+ return AUTHZ_GRANTED;
+ else
+ return AUTHZ_DENIED;
+}
+
+static const char *ssl_authz_require_ssl_parse(cmd_parms *cmd,
+ const char *require_line,
+ const void **parsed)
+{
+ if (require_line && require_line[0])
+ return "'Require ssl' does not take arguments";
+
+ return NULL;
+}
+
+const authz_provider ssl_authz_provider_require_ssl =
+{
+ &ssl_authz_require_ssl_check,
+ &ssl_authz_require_ssl_parse,
+};
+
+static authz_status ssl_authz_verify_client_check(request_rec *r,
+ const char *require_line,
+ const void *parsed)
+{
+ SSLConnRec *sslconn = myConnConfig(r->connection);
+ SSL *ssl = sslconn ? sslconn->ssl : NULL;
+
+ if (!ssl)
+ return AUTHZ_DENIED;
+
+ if (sslconn->verify_error == NULL &&
+ sslconn->verify_info == NULL &&
+ SSL_get_verify_result(ssl) == X509_V_OK)
+ {
+ X509 *xs = SSL_get_peer_certificate(ssl);
+
+ if (xs) {
+ X509_free(xs);
+ return AUTHZ_GRANTED;
+ }
+ else {
+ X509_free(xs);
+ }
+ }
+
+ return AUTHZ_DENIED;
+}
+
+static const char *ssl_authz_verify_client_parse(cmd_parms *cmd,
+ const char *require_line,
+ const void **parsed)
+{
+ if (require_line && require_line[0])
+ return "'Require ssl-verify-client' does not take arguments";
+
+ return NULL;
+}
+
+const authz_provider ssl_authz_provider_verify_client =
+{
+ &ssl_authz_verify_client_check,
+ &ssl_authz_verify_client_parse,
+};
+
+
+
+/* _________________________________________________________________
+**
** OpenSSL Callback Functions
** _________________________________________________________________
*/
@@ -1239,7 +1329,7 @@ RSA *ssl_callback_TmpRSA(SSL *ssl, int export, int keylen)
SSLModConfigRec *mc = myModConfigFromConn(c);
int idx;
- ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
"handing out temporary %d bit RSA key", keylen);
/* doesn't matter if export flag is on,
@@ -1271,7 +1361,7 @@ DH *ssl_callback_TmpDH(SSL *ssl, int export, int keylen)
SSLModConfigRec *mc = myModConfigFromConn(c);
int idx;
- ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
"handing out temporary %d bit DH key", keylen);
switch (keylen) {
@@ -1287,6 +1377,31 @@ DH *ssl_callback_TmpDH(SSL *ssl, int export, int keylen)
return (DH *)mc->pTmpKeys[idx];
}
+#ifndef OPENSSL_NO_EC
+EC_KEY *ssl_callback_TmpECDH(SSL *ssl, int export, int keylen)
+{
+ conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
+ static EC_KEY *ecdh = NULL;
+ static int init = 0;
+
+ /* XXX Uses 256-bit key for now. TODO: support other sizes. */
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
+ "handing out temporary 256 bit ECC key");
+
+ if (init == 0) {
+ ecdh = EC_KEY_new();
+ if (ecdh != NULL) {
+ /* ecdh->group = EC_GROUP_new_by_nid(NID_secp160r2); */
+ EC_KEY_set_group(ecdh,
+ EC_GROUP_new_by_curve_name(NID_X9_62_prime256v1));
+ }
+ init = 1;
+ }
+
+ return ecdh;
+}
+#endif
+
/*
* This OpenSSL callback function is called when OpenSSL
* does client authentication and verifies the certificate chain.
@@ -1313,26 +1428,13 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx)
/*
* Log verification information
*/
- if (s->loglevel >= APLOG_DEBUG) {
- X509 *cert = X509_STORE_CTX_get_current_cert(ctx);
- char *sname = X509_NAME_oneline(X509_get_subject_name(cert), NULL, 0);
- char *iname = X509_NAME_oneline(X509_get_issuer_name(cert), NULL, 0);
-
- ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, conn,
- "Certificate Verification: "
- "depth: %d, subject: %s, issuer: %s",
- errdepth,
- sname ? sname : "-unknown-",
- iname ? iname : "-unknown-");
-
- if (sname) {
- modssl_free(sname);
- }
-
- if (iname) {
- modssl_free(iname);
- }
- }
+ ssl_log_cxerror(SSLLOG_MARK, APLOG_DEBUG, 0, conn,
+ X509_STORE_CTX_get_current_cert(ctx), APLOGNO(02275)
+ "Certificate Verification, depth %d, "
+ "CRL checking mode: %s", errdepth,
+ mctx->crl_check_mode == SSL_CRLCHECK_CHAIN ?
+ "chain" : (mctx->crl_check_mode == SSL_CRLCHECK_LEAF ?
+ "leaf" : "none"));
/*
* Check for optionally acceptable non-verifiable issuer situation
@@ -1356,7 +1458,7 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx)
if (ssl_verify_error_is_optional(errnum) &&
(verify == SSL_CVERIFY_OPTIONAL_NO_CA))
{
- ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, conn,
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, conn, APLOGNO(02037)
"Certificate Verification: Verifiable Issuer is "
"configured as optional, therefore we're accepting "
"the certificate");
@@ -1366,21 +1468,60 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx)
}
/*
- * Additionally perform CRL-based revocation checks
+ * Expired certificates vs. "expired" CRLs: by default, OpenSSL
+ * turns X509_V_ERR_CRL_HAS_EXPIRED into a "certificate_expired(45)"
+ * SSL alert, but that's not really the message we should convey to the
+ * peer (at the very least, it's confusing, and in many cases, it's also
+ * inaccurate, as the certificate itself may very well not have expired
+ * yet). We set the X509_STORE_CTX error to something which OpenSSL's
+ * s3_both.c:ssl_verify_alarm_type() maps to SSL_AD_CERTIFICATE_UNKNOWN,
+ * i.e. the peer will receive a "certificate_unknown(46)" alert.
+ * We do not touch errnum, though, so that later on we will still log
+ * the "real" error, as returned by OpenSSL.
*/
- if (ok) {
- if (!(ok = ssl_callback_SSLVerify_CRL(ok, ctx, conn))) {
- errnum = X509_STORE_CTX_get_error(ctx);
+ if (!ok && errnum == X509_V_ERR_CRL_HAS_EXPIRED) {
+ X509_STORE_CTX_set_error(ctx, -1);
+ }
+
+#ifndef OPENSSL_NO_OCSP
+ /*
+ * Perform OCSP-based revocation checks
+ */
+ if (ok && sc->server->ocsp_enabled) {
+ /* If there was an optional verification error, it's not
+ * possible to perform OCSP validation since the issuer may be
+ * missing/untrusted. Fail in that case. */
+ if (ssl_verify_error_is_optional(errnum)) {
+ X509_STORE_CTX_set_error(ctx, X509_V_ERR_APPLICATION_VERIFICATION);
+ errnum = X509_V_ERR_APPLICATION_VERIFICATION;
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, conn, APLOGNO(02038)
+ "cannot perform OCSP validation for cert "
+ "if issuer has not been verified "
+ "(optional_no_ca configured)");
+ ok = FALSE;
+ } else {
+ ok = modssl_verify_ocsp(ctx, sc, s, conn, conn->pool);
+ if (!ok) {
+ errnum = X509_STORE_CTX_get_error(ctx);
+ }
}
}
+#endif
/*
* If we already know it's not ok, log the real reason
*/
if (!ok) {
- ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, conn,
- "Certificate Verification: Error (%d): %s",
- errnum, X509_verify_cert_error_string(errnum));
+ if (APLOGcinfo(conn)) {
+ ssl_log_cxerror(SSLLOG_MARK, APLOG_INFO, 0, conn,
+ X509_STORE_CTX_get_current_cert(ctx), APLOGNO(02276)
+ "Certificate Verification: Error (%d): %s",
+ errnum, X509_verify_cert_error_string(errnum));
+ } else {
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, conn, APLOGNO(02039)
+ "Certificate Verification: Error (%d): %s",
+ errnum, X509_verify_cert_error_string(errnum));
+ }
if (sslconn->client_cert) {
X509_free(sslconn->client_cert);
@@ -1401,7 +1542,7 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx)
}
if (errdepth > depth) {
- ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, conn,
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, conn, APLOGNO(02040)
"Certificate Verification: Certificate Chain too long "
"(chain has %d certificates, but maximum allowed are "
"only %d)",
@@ -1419,220 +1560,16 @@ int ssl_callback_SSLVerify(int ok, X509_STORE_CTX *ctx)
return ok;
}
-int ssl_callback_SSLVerify_CRL(int ok, X509_STORE_CTX *ctx, conn_rec *c)
-{
- SSL *ssl = X509_STORE_CTX_get_ex_data(ctx,
- SSL_get_ex_data_X509_STORE_CTX_idx());
- request_rec *r = (request_rec *)SSL_get_app_data2(ssl);
- server_rec *s = r ? r->server : mySrvFromConn(c);
- SSLSrvConfigRec *sc = mySrvConfig(s);
- SSLConnRec *sslconn = myConnConfig(c);
- modssl_ctx_t *mctx = myCtxConfig(sslconn, sc);
- X509_OBJECT obj;
- X509_NAME *subject, *issuer;
- X509 *cert;
- X509_CRL *crl;
- EVP_PKEY *pubkey;
- int i, n, rc;
-
- /*
- * Unless a revocation store for CRLs was created we
- * cannot do any CRL-based verification, of course.
- */
- if (!mctx->crl) {
- return ok;
- }
-
- /*
- * Determine certificate ingredients in advance
- */
- cert = X509_STORE_CTX_get_current_cert(ctx);
- subject = X509_get_subject_name(cert);
- issuer = X509_get_issuer_name(cert);
-
- /*
- * OpenSSL provides the general mechanism to deal with CRLs but does not
- * use them automatically when verifying certificates, so we do it
- * explicitly here. We will check the CRL for the currently checked
- * certificate, if there is such a CRL in the store.
- *
- * We come through this procedure for each certificate in the certificate
- * chain, starting with the root-CA's certificate. At each step we've to
- * both verify the signature on the CRL (to make sure it's a valid CRL)
- * and it's revocation list (to make sure the current certificate isn't
- * revoked). But because to check the signature on the CRL we need the
- * public key of the issuing CA certificate (which was already processed
- * one round before), we've a little problem. But we can both solve it and
- * at the same time optimize the processing by using the following
- * verification scheme (idea and code snippets borrowed from the GLOBUS
- * project):
- *
- * 1. We'll check the signature of a CRL in each step when we find a CRL
- * through the _subject_ name of the current certificate. This CRL
- * itself will be needed the first time in the next round, of course.
- * But we do the signature processing one round before this where the
- * public key of the CA is available.
- *
- * 2. We'll check the revocation list of a CRL in each step when
- * we find a CRL through the _issuer_ name of the current certificate.
- * This CRLs signature was then already verified one round before.
- *
- * This verification scheme allows a CA to revoke its own certificate as
- * well, of course.
- */
-
- /*
- * Try to retrieve a CRL corresponding to the _subject_ of
- * the current certificate in order to verify it's integrity.
- */
- memset((char *)&obj, 0, sizeof(obj));
- rc = SSL_X509_STORE_lookup(mctx->crl,
- X509_LU_CRL, subject, &obj);
- crl = obj.data.crl;
-
- if ((rc > 0) && crl) {
- /*
- * Log information about CRL
- * (A little bit complicated because of ASN.1 and BIOs...)
- */
- if (s->loglevel >= APLOG_DEBUG) {
- char buff[512]; /* should be plenty */
- BIO *bio = BIO_new(BIO_s_mem());
-
- BIO_printf(bio, "CA CRL: Issuer: ");
- X509_NAME_print(bio, issuer, 0);
-
- BIO_printf(bio, ", lastUpdate: ");
- ASN1_UTCTIME_print(bio, X509_CRL_get_lastUpdate(crl));
-
- BIO_printf(bio, ", nextUpdate: ");
- ASN1_UTCTIME_print(bio, X509_CRL_get_nextUpdate(crl));
-
- n = BIO_read(bio, buff, sizeof(buff) - 1);
- buff[n] = '\0';
-
- BIO_free(bio);
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "%s", buff);
- }
-
- /*
- * Verify the signature on this CRL
- */
- pubkey = X509_get_pubkey(cert);
- rc = X509_CRL_verify(crl, pubkey);
-#ifdef OPENSSL_VERSION_NUMBER
- /* Only refcounted in OpenSSL */
- if (pubkey)
- EVP_PKEY_free(pubkey);
-#endif
- if (rc <= 0) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
- "Invalid signature on CRL");
-
- X509_STORE_CTX_set_error(ctx, X509_V_ERR_CRL_SIGNATURE_FAILURE);
- X509_OBJECT_free_contents(&obj);
- return FALSE;
- }
-
- /*
- * Check date of CRL to make sure it's not expired
- */
- i = X509_cmp_current_time(X509_CRL_get_nextUpdate(crl));
-
- if (i == 0) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
- "Found CRL has invalid nextUpdate field");
-
- X509_STORE_CTX_set_error(ctx,
- X509_V_ERR_ERROR_IN_CRL_NEXT_UPDATE_FIELD);
- X509_OBJECT_free_contents(&obj);
-
- return FALSE;
- }
-
- if (i < 0) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
- "Found CRL is expired - "
- "revoking all certificates until you get updated CRL");
-
- X509_STORE_CTX_set_error(ctx, X509_V_ERR_CRL_HAS_EXPIRED);
- X509_OBJECT_free_contents(&obj);
-
- return FALSE;
- }
-
- X509_OBJECT_free_contents(&obj);
- }
-
- /*
- * Try to retrieve a CRL corresponding to the _issuer_ of
- * the current certificate in order to check for revocation.
- */
- memset((char *)&obj, 0, sizeof(obj));
- rc = SSL_X509_STORE_lookup(mctx->crl,
- X509_LU_CRL, issuer, &obj);
-
- crl = obj.data.crl;
- if ((rc > 0) && crl) {
- /*
- * Check if the current certificate is revoked by this CRL
- */
- n = sk_X509_REVOKED_num(X509_CRL_get_REVOKED(crl));
-
- for (i = 0; i < n; i++) {
- X509_REVOKED *revoked =
- sk_X509_REVOKED_value(X509_CRL_get_REVOKED(crl), i);
-
- ASN1_INTEGER *sn = X509_REVOKED_get_serialNumber(revoked);
-
- if (!ASN1_INTEGER_cmp(sn, X509_get_serialNumber(cert))) {
- if (s->loglevel >= APLOG_DEBUG) {
- char *cp = X509_NAME_oneline(issuer, NULL, 0);
- long serial = ASN1_INTEGER_get(sn);
-
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
- "Certificate with serial %ld (0x%lX) "
- "revoked per CRL from issuer %s",
- serial, serial, cp);
- modssl_free(cp);
- }
-
- X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REVOKED);
- X509_OBJECT_free_contents(&obj);
-
- return FALSE;
- }
- }
-
- X509_OBJECT_free_contents(&obj);
- }
-
- return ok;
-}
-
#define SSLPROXY_CERT_CB_LOG_FMT \
"Proxy client certificate callback: (%s) "
-static void modssl_proxy_info_log(server_rec *s,
+static void modssl_proxy_info_log(conn_rec *c,
X509_INFO *info,
const char *msg)
{
- SSLSrvConfigRec *sc = mySrvConfig(s);
- char name_buf[256];
- X509_NAME *name;
- char *dn;
-
- if (s->loglevel < APLOG_DEBUG) {
- return;
- }
-
- name = X509_get_subject_name(info->x509);
- dn = X509_NAME_oneline(name, name_buf, sizeof(name_buf));
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- SSLPROXY_CERT_CB_LOG_FMT "%s, sending %s",
- sc->vhost_id, msg, dn ? dn : "-uknown-");
+ ssl_log_cxerror(SSLLOG_MARK, APLOG_DEBUG, 0, c, info->x509, APLOGNO(02277)
+ SSLPROXY_CERT_CB_LOG_FMT "%s, sending",
+ (mySrvConfigFromConn(c))->vhost_id, msg);
}
/*
@@ -1642,27 +1579,30 @@ static void modssl_proxy_info_log(server_rec *s,
*/
#define modssl_set_cert_info(info, cert, pkey) \
*cert = info->x509; \
- X509_reference_inc(*cert); \
+ CRYPTO_add(&(*cert)->references, +1, CRYPTO_LOCK_X509); \
*pkey = info->x_pkey->dec_pkey; \
- EVP_PKEY_reference_inc(*pkey)
+ CRYPTO_add(&(*pkey)->references, +1, CRYPTO_LOCK_X509_PKEY)
-int ssl_callback_proxy_cert(SSL *ssl, MODSSL_CLIENT_CERT_CB_ARG_TYPE **x509, EVP_PKEY **pkey)
+int ssl_callback_proxy_cert(SSL *ssl, X509 **x509, EVP_PKEY **pkey)
{
conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
server_rec *s = mySrvFromConn(c);
SSLSrvConfigRec *sc = mySrvConfig(s);
- X509_NAME *ca_name, *issuer;
+ X509_NAME *ca_name, *issuer, *ca_issuer;
X509_INFO *info;
+ X509 *ca_cert;
STACK_OF(X509_NAME) *ca_list;
STACK_OF(X509_INFO) *certs = sc->proxy->pkp->certs;
- int i, j;
+ STACK_OF(X509) *ca_certs;
+ STACK_OF(X509) **ca_cert_chains;
+ int i, j, k;
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02267)
SSLPROXY_CERT_CB_LOG_FMT "entered",
sc->vhost_id);
if (!certs || (sk_X509_INFO_num(certs) <= 0)) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(02268)
SSLPROXY_CERT_CB_LOG_FMT
"downstream server wanted client certificate "
"but none are configured", sc->vhost_id);
@@ -1678,13 +1618,14 @@ int ssl_callback_proxy_cert(SSL *ssl, MODSSL_CLIENT_CERT_CB_ARG_TYPE **x509, EVP
*/
info = sk_X509_INFO_value(certs, 0);
- modssl_proxy_info_log(s, info, "no acceptable CA list");
+ modssl_proxy_info_log(c, info, APLOGNO(02278) "no acceptable CA list");
modssl_set_cert_info(info, x509, pkey);
return TRUE;
}
+ ca_cert_chains = sc->proxy->pkp->ca_certs;
for (i = 0; i < sk_X509_NAME_num(ca_list); i++) {
ca_name = sk_X509_NAME_value(ca_list, i);
@@ -1692,17 +1633,40 @@ int ssl_callback_proxy_cert(SSL *ssl, MODSSL_CLIENT_CERT_CB_ARG_TYPE **x509, EVP
info = sk_X509_INFO_value(certs, j);
issuer = X509_get_issuer_name(info->x509);
+ /* Search certs (by issuer name) one by one*/
if (X509_NAME_cmp(issuer, ca_name) == 0) {
- modssl_proxy_info_log(s, info, "found acceptable cert");
+ modssl_proxy_info_log(c, info, APLOGNO(02279)
+ "found acceptable cert");
modssl_set_cert_info(info, x509, pkey);
return TRUE;
}
- }
+
+ if (ca_cert_chains) {
+ /*
+ * Failed to find direct issuer - search intermediates
+ * (by issuer name), if provided.
+ */
+ ca_certs = ca_cert_chains[j];
+ for (k = 0; k < sk_X509_num(ca_certs); k++) {
+ ca_cert = sk_X509_value(ca_certs, k);
+ ca_issuer = X509_get_issuer_name(ca_cert);
+
+ if(X509_NAME_cmp(ca_issuer, ca_name) == 0 ) {
+ modssl_proxy_info_log(c, info, APLOGNO(02280)
+ "found acceptable cert by intermediate CA");
+
+ modssl_set_cert_info(info, x509, pkey);
+
+ return TRUE;
+ }
+ } /* end loop through chained certs */
+ }
+ } /* end loop through available certs */
}
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02269)
SSLPROXY_CERT_CB_LOG_FMT
"no client certificate found!?", sc->vhost_id);
@@ -1720,7 +1684,7 @@ static void ssl_session_log(server_rec *s,
char buf[SSL_SESSION_ID_STRING_LEN];
char timeout_str[56] = {'\0'};
- if (s->loglevel < APLOG_DEBUG) {
+ if (!APLOGdebug(s)) {
return;
}
@@ -1729,7 +1693,7 @@ static void ssl_session_log(server_rec *s,
"timeout=%lds ", (timeout - time(NULL)));
}
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, s,
"Inter-Process Session Cache: "
"request=%s status=%s id=%s %s(session %s)",
request, status,
@@ -1764,12 +1728,13 @@ int ssl_callback_NewSessionCacheEntry(SSL *ssl, SSL_SESSION *session)
* Store the SSL_SESSION in the inter-process cache with the
* same expire time, so it expires automatically there, too.
*/
- id = SSL_SESSION_get_session_id(session);
- idlen = SSL_SESSION_get_session_id_length(session);
-
- timeout += modssl_session_get_time(session);
+ id = session->session_id;
+ idlen = session->session_id_length;
- rc = ssl_scache_store(s, id, idlen, timeout, session);
+ rc = ssl_scache_store(s, id, idlen,
+ apr_time_from_sec(SSL_SESSION_get_time(session)
+ + timeout),
+ session, conn->pool);
ssl_session_log(s, "SET", id, idlen,
rc == TRUE ? "OK" : "BAD",
@@ -1801,7 +1766,7 @@ SSL_SESSION *ssl_callback_GetSessionCacheEntry(SSL *ssl,
/*
* Try to retrieve the SSL_SESSION from the inter-process cache
*/
- session = ssl_scache_retrieve(s, id, idlen);
+ session = ssl_scache_retrieve(s, id, idlen, conn->pool);
ssl_session_log(s, "GET", id, idlen,
session ? "FOUND" : "MISSED",
@@ -1844,10 +1809,11 @@ void ssl_callback_DelSessionCacheEntry(SSL_CTX *ctx,
/*
* Remove the SSL_SESSION from the inter-process cache
*/
- id = SSL_SESSION_get_session_id(session);
- idlen = SSL_SESSION_get_session_id_length(session);
+ id = session->session_id;
+ idlen = session->session_id_length;
- ssl_scache_remove(s, id, idlen);
+ /* TODO: Do we need a temp pool here, or are we always shutting down? */
+ ssl_scache_remove(s, id, idlen, sc->mc->pPool);
ssl_session_log(s, "REM", id, idlen,
"OK", "dead", 0);
@@ -1856,70 +1822,70 @@ void ssl_callback_DelSessionCacheEntry(SSL_CTX *ctx,
}
/* Dump debugginfo trace to the log file. */
-static void log_tracing_state(MODSSL_INFO_CB_ARG_TYPE ssl, conn_rec *c,
+static void log_tracing_state(const SSL *ssl, conn_rec *c,
server_rec *s, int where, int rc)
{
/*
* create the various trace messages
*/
if (where & SSL_CB_HANDSHAKE_START) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "%s: Handshake: start", SSL_LIBRARY_NAME);
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, c,
+ "%s: Handshake: start", SSL_LIBRARY_NAME);
}
else if (where & SSL_CB_HANDSHAKE_DONE) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "%s: Handshake: done", SSL_LIBRARY_NAME);
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, c,
+ "%s: Handshake: done", SSL_LIBRARY_NAME);
}
else if (where & SSL_CB_LOOP) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "%s: Loop: %s",
- SSL_LIBRARY_NAME, SSL_state_string_long(ssl));
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, c,
+ "%s: Loop: %s",
+ SSL_LIBRARY_NAME, SSL_state_string_long(ssl));
}
else if (where & SSL_CB_READ) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "%s: Read: %s",
- SSL_LIBRARY_NAME, SSL_state_string_long(ssl));
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, c,
+ "%s: Read: %s",
+ SSL_LIBRARY_NAME, SSL_state_string_long(ssl));
}
else if (where & SSL_CB_WRITE) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "%s: Write: %s",
- SSL_LIBRARY_NAME, SSL_state_string_long(ssl));
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, c,
+ "%s: Write: %s",
+ SSL_LIBRARY_NAME, SSL_state_string_long(ssl));
}
else if (where & SSL_CB_ALERT) {
char *str = (where & SSL_CB_READ) ? "read" : "write";
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "%s: Alert: %s:%s:%s",
- SSL_LIBRARY_NAME, str,
- SSL_alert_type_string_long(rc),
- SSL_alert_desc_string_long(rc));
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, c,
+ "%s: Alert: %s:%s:%s",
+ SSL_LIBRARY_NAME, str,
+ SSL_alert_type_string_long(rc),
+ SSL_alert_desc_string_long(rc));
}
else if (where & SSL_CB_EXIT) {
if (rc == 0) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "%s: Exit: failed in %s",
- SSL_LIBRARY_NAME, SSL_state_string_long(ssl));
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, c,
+ "%s: Exit: failed in %s",
+ SSL_LIBRARY_NAME, SSL_state_string_long(ssl));
}
else if (rc < 0) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "%s: Exit: error in %s",
- SSL_LIBRARY_NAME, SSL_state_string_long(ssl));
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE3, 0, c,
+ "%s: Exit: error in %s",
+ SSL_LIBRARY_NAME, SSL_state_string_long(ssl));
}
}
/*
- * Because SSL renegotations can happen at any time (not only after
+ * Because SSL renegotiations can happen at any time (not only after
* SSL_accept()), the best way to log the current connection details is
* right after a finished handshake.
*/
if (where & SSL_CB_HANDSHAKE_DONE) {
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
- "Connection: Client IP: %s, Protocol: %s, "
- "Cipher: %s (%s/%s bits)",
- ssl_var_lookup(NULL, s, c, NULL, "REMOTE_ADDR"),
- ssl_var_lookup(NULL, s, c, NULL, "SSL_PROTOCOL"),
- ssl_var_lookup(NULL, s, c, NULL, "SSL_CIPHER"),
- ssl_var_lookup(NULL, s, c, NULL, "SSL_CIPHER_USEKEYSIZE"),
- ssl_var_lookup(NULL, s, c, NULL, "SSL_CIPHER_ALGKEYSIZE"));
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(02041)
+ "Connection: Client IP: %s, Protocol: %s, "
+ "Cipher: %s (%s/%s bits)",
+ ssl_var_lookup(NULL, s, c, NULL, "REMOTE_ADDR"),
+ ssl_var_lookup(NULL, s, c, NULL, "SSL_PROTOCOL"),
+ ssl_var_lookup(NULL, s, c, NULL, "SSL_CIPHER"),
+ ssl_var_lookup(NULL, s, c, NULL, "SSL_CIPHER_USEKEYSIZE"),
+ ssl_var_lookup(NULL, s, c, NULL, "SSL_CIPHER_ALGKEYSIZE"));
}
}
@@ -1929,7 +1895,7 @@ static void log_tracing_state(MODSSL_INFO_CB_ARG_TYPE ssl, conn_rec *c,
* client-initiated renegotiations, and for dumping everything to the
* log.
*/
-void ssl_callback_Info(MODSSL_INFO_CB_ARG_TYPE ssl, int where, int rc)
+void ssl_callback_Info(const SSL *ssl, int where, int rc)
{
conn_rec *c;
server_rec *s;
@@ -1948,12 +1914,12 @@ void ssl_callback_Info(MODSSL_INFO_CB_ARG_TYPE ssl, int where, int rc)
* state machine and move to ABORT if a Client Hello is being
* read. */
if ((where & SSL_CB_ACCEPT_LOOP) && scr->reneg_state == RENEG_REJECT) {
- int state = SSL_get_state(ssl);
-
- if (state == SSL3_ST_SR_CLNT_HELLO_A
+ int state = SSL_get_state((SSL *)ssl);
+
+ if (state == SSL3_ST_SR_CLNT_HELLO_A
|| state == SSL23_ST_SR_CLNT_HELLO_A) {
scr->reneg_state = RENEG_ABORT;
- ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c,
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(02042)
"rejecting client initiated renegotiation");
}
}
@@ -1964,7 +1930,7 @@ void ssl_callback_Info(MODSSL_INFO_CB_ARG_TYPE ssl, int where, int rc)
}
s = mySrvFromConn(c);
- if (s && s->loglevel >= APLOG_DEBUG) {
+ if (s && APLOGdebug(s)) {
log_tracing_state(ssl, c, s, where, rc);
}
}
@@ -1984,13 +1950,13 @@ int ssl_callback_ServerNameIndication(SSL *ssl, int *al, modssl_ctx_t *mctx)
if (c) {
if (ap_vhost_iterate_given_conn(c, ssl_find_vhost,
(void *)servername)) {
- ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(02043)
"SSL virtual host for servername %s found",
servername);
return SSL_TLSEXT_ERR_OK;
}
else {
- ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(02044)
"No matching SSL virtual host for servername "
"%s found (using default/first virtual host)",
servername);
@@ -2007,7 +1973,7 @@ int ssl_callback_ServerNameIndication(SSL *ssl, int *al, modssl_ctx_t *mctx)
* or one of the ServerAliases matches the supplied name (to be used
* with ap_vhost_iterate_given_conn())
*/
-static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s)
+static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s)
{
SSLSrvConfigRec *sc;
SSL *ssl;
@@ -2021,7 +1987,7 @@ static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s)
found = TRUE;
}
- /*
+ /*
* if not matched yet, check ServerAlias entries
* (adapted from vhost.c:matches_aliases())
*/
@@ -2081,6 +2047,23 @@ static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s)
}
/*
+ * Adjust the session id context. ssl_init_ssl_connection()
+ * always picks the configuration of the first vhost when
+ * calling SSL_new(), but we want to tie the session to the
+ * vhost we have just switched to. Again, we have to make sure
+ * that we're not overwriting a session id context which was
+ * possibly set in ssl_hook_Access(), before triggering
+ * a renegotation.
+ */
+ if (SSL_num_renegotiations(ssl) == 0) {
+ unsigned char *sid_ctx =
+ (unsigned char *)ap_md5_binary(c->pool,
+ (unsigned char *)sc->vhost_id,
+ sc->vhost_id_len);
+ SSL_set_session_id_context(ssl, sid_ctx, APR_MD5_DIGESTSIZE*2);
+ }
+
+ /*
* Save the found server into our SSLConnRec for later
* retrieval
*/
@@ -2090,10 +2073,10 @@ static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s)
* There is one special filter callback, which is set
* very early depending on the base_server's log level.
* If this is not the first vhost we're now selecting
- * (and the first vhost doesn't use APLOG_DEBUG), then
+ * (and the first vhost doesn't use APLOG_TRACE4), then
* we need to set that callback here.
*/
- if (s->loglevel >= APLOG_DEBUG) {
+ if (APLOGtrace4(s)) {
BIO_set_callback(SSL_get_rbio(ssl), ssl_io_data_cb);
BIO_set_callback_arg(SSL_get_rbio(ssl), (void *)ssl);
}
@@ -2104,3 +2087,73 @@ static int ssl_find_vhost(void *servername, conn_rec *c, server_rec *s)
return 0;
}
#endif
+
+#ifdef HAVE_TLS_SESSION_TICKETS
+/*
+ * This callback function is executed when OpenSSL needs a key for encrypting/
+ * decrypting a TLS session ticket (RFC 5077) and a ticket key file has been
+ * configured through SSLSessionTicketKeyFile.
+ */
+int ssl_callback_SessionTicket(SSL *ssl,
+ unsigned char *keyname,
+ unsigned char *iv,
+ EVP_CIPHER_CTX *cipher_ctx,
+ HMAC_CTX *hctx,
+ int mode)
+{
+ conn_rec *c = (conn_rec *)SSL_get_app_data(ssl);
+ server_rec *s = mySrvFromConn(c);
+ SSLSrvConfigRec *sc = mySrvConfig(s);
+ SSLConnRec *sslconn = myConnConfig(c);
+ modssl_ctx_t *mctx = myCtxConfig(sslconn, sc);
+ modssl_ticket_key_t *ticket_key = mctx->ticket_key;
+
+ if (mode == 1) {
+ /*
+ * OpenSSL is asking for a key for encrypting a ticket,
+ * see s3_srvr.c:ssl3_send_newsession_ticket()
+ */
+
+ if (ticket_key == NULL) {
+ /* should never happen, but better safe than sorry */
+ return -1;
+ }
+
+ memcpy(keyname, ticket_key->key_name, 16);
+ RAND_pseudo_bytes(iv, EVP_MAX_IV_LENGTH);
+ EVP_EncryptInit_ex(cipher_ctx, EVP_aes_128_cbc(), NULL,
+ ticket_key->aes_key, iv);
+ HMAC_Init_ex(hctx, ticket_key->hmac_secret, 16, tlsext_tick_md(), NULL);
+
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(02289)
+ "TLS session ticket key for %s successfully set, "
+ "creating new session ticket", sc->vhost_id);
+
+ return 0;
+ }
+ else if (mode == 0) {
+ /*
+ * OpenSSL is asking for the decryption key,
+ * see t1_lib.c:tls_decrypt_ticket()
+ */
+
+ /* check key name */
+ if (ticket_key == NULL || memcmp(keyname, ticket_key->key_name, 16)) {
+ return 0;
+ }
+
+ EVP_DecryptInit_ex(cipher_ctx, EVP_aes_128_cbc(), NULL,
+ ticket_key->aes_key, iv);
+ HMAC_Init_ex(hctx, ticket_key->hmac_secret, 16, tlsext_tick_md(), NULL);
+
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(02290)
+ "TLS session ticket key for %s successfully set, "
+ "decrypting existing session ticket", sc->vhost_id);
+
+ return 1;
+ }
+
+ /* OpenSSL is not expected to call us with modes other than 1 or 0 */
+ return -1;
+}
+#endif
diff --git a/modules/ssl/ssl_engine_log.c b/modules/ssl/ssl_engine_log.c
index 883274bf..31861ca7 100644
--- a/modules/ssl/ssl_engine_log.c
+++ b/modules/ssl/ssl_engine_log.c
@@ -79,23 +79,155 @@ void ssl_die(void)
void ssl_log_ssl_error(const char *file, int line, int level, server_rec *s)
{
unsigned long e;
+ const char *data;
+ int flags;
- while ((e = ERR_get_error())) {
+ while ((e = ERR_peek_error_line_data(NULL, NULL, &data, &flags))) {
const char *annotation;
char err[256];
+ if (!(flags & ERR_TXT_STRING)) {
+ data = NULL;
+ }
+
ERR_error_string_n(e, err, sizeof err);
annotation = ssl_log_annotation(err);
- if (annotation) {
- ap_log_error(file, line, level, 0, s,
- "SSL Library Error: %lu %s %s",
- e, err, annotation);
- }
- else {
- ap_log_error(file, line, level, 0, s,
- "SSL Library Error: %lu %s",
- e, err);
+ ap_log_error(file, line, APLOG_MODULE_INDEX, level, 0, s,
+ "SSL Library Error: %s%s%s%s%s%s",
+ /* %s */
+ err,
+ /* %s%s%s */
+ data ? " (" : "", data ? data : "", data ? ")" : "",
+ /* %s%s */
+ annotation ? " -- " : "",
+ annotation ? annotation : "");
+
+ /* Pop the error off the stack: */
+ ERR_get_error();
+ }
+}
+
+static void ssl_log_cert_error(const char *file, int line, int level,
+ apr_status_t rv, const server_rec *s,
+ const conn_rec *c, const request_rec *r,
+ apr_pool_t *p, X509 *cert, const char *format,
+ va_list ap)
+{
+ char buf[HUGE_STRING_LEN];
+ int msglen, n;
+ char *name;
+
+ apr_vsnprintf(buf, sizeof buf, format, ap);
+
+ msglen = strlen(buf);
+
+ if (cert) {
+ BIO *bio = BIO_new(BIO_s_mem());
+
+ if (bio) {
+ /*
+ * Limit the maximum length of the subject and issuer DN strings
+ * in the log message. 300 characters should always be sufficient
+ * for holding both the timestamp, module name, pid etc. stuff
+ * at the beginning of the line and the trailing information about
+ * serial, notbefore and notafter.
+ */
+ int maxdnlen = (HUGE_STRING_LEN - msglen - 300) / 2;
+
+ BIO_puts(bio, " [subject: ");
+ name = SSL_X509_NAME_to_string(p, X509_get_subject_name(cert),
+ maxdnlen);
+ if (!strIsEmpty(name)) {
+ BIO_puts(bio, name);
+ } else {
+ BIO_puts(bio, "-empty-");
+ }
+
+ BIO_puts(bio, " / issuer: ");
+ name = SSL_X509_NAME_to_string(p, X509_get_issuer_name(cert),
+ maxdnlen);
+ if (!strIsEmpty(name)) {
+ BIO_puts(bio, name);
+ } else {
+ BIO_puts(bio, "-empty-");
+ }
+
+ BIO_puts(bio, " / serial: ");
+ if (i2a_ASN1_INTEGER(bio, X509_get_serialNumber(cert)) == -1)
+ BIO_puts(bio, "(ERROR)");
+
+ BIO_puts(bio, " / notbefore: ");
+ ASN1_TIME_print(bio, X509_get_notBefore(cert));
+
+ BIO_puts(bio, " / notafter: ");
+ ASN1_TIME_print(bio, X509_get_notAfter(cert));
+
+ BIO_puts(bio, "]");
+
+ n = BIO_read(bio, buf + msglen, sizeof buf - msglen - 1);
+ if (n > 0)
+ buf[msglen + n] = '\0';
+
+ BIO_free(bio);
}
}
+ else {
+ apr_snprintf(buf + msglen, sizeof buf - msglen,
+ " [certificate: -not available-]");
+ }
+
+ if (r) {
+ ap_log_rerror(file, line, APLOG_MODULE_INDEX, level, rv, r, "%s", buf);
+ }
+ else if (c) {
+ ap_log_cerror(file, line, APLOG_MODULE_INDEX, level, rv, c, "%s", buf);
+ }
+ else if (s) {
+ ap_log_error(file, line, APLOG_MODULE_INDEX, level, rv, s, "%s", buf);
+ }
+
+}
+
+/*
+ * Wrappers for ap_log_error/ap_log_cerror/ap_log_rerror which log additional
+ * details of the X509 cert. For ssl_log_xerror, a pool needs to be passed in
+ * as well (for temporary allocation of the cert's subject/issuer name strings,
+ * in the other cases we use the connection and request pool, respectively).
+ */
+void ssl_log_xerror(const char *file, int line, int level, apr_status_t rv,
+ apr_pool_t *ptemp, server_rec *s, X509 *cert,
+ const char *fmt, ...)
+{
+ if (APLOG_IS_LEVEL(s,level)) {
+ va_list ap;
+ va_start(ap, fmt);
+ ssl_log_cert_error(file, line, level, rv, s, NULL, NULL, ptemp,
+ cert, fmt, ap);
+ va_end(ap);
+ }
+}
+
+void ssl_log_cxerror(const char *file, int line, int level, apr_status_t rv,
+ conn_rec *c, X509 *cert, const char *fmt, ...)
+{
+ if (APLOG_IS_LEVEL(mySrvFromConn(c),level)) {
+ va_list ap;
+ va_start(ap, fmt);
+ ssl_log_cert_error(file, line, level, rv, NULL, c, NULL, c->pool,
+ cert, fmt, ap);
+ va_end(ap);
+ }
+}
+
+void ssl_log_rxerror(const char *file, int line, int level, apr_status_t rv,
+ request_rec *r, X509 *cert, const char *fmt, ...)
+{
+ if (APLOG_R_IS_LEVEL(r,level)) {
+ va_list ap;
+ va_start(ap, fmt);
+ ssl_log_cert_error(file, line, level, rv, NULL, NULL, r, r->pool,
+ cert, fmt, ap);
+ va_end(ap);
+ }
}
diff --git a/modules/ssl/ssl_engine_mutex.c b/modules/ssl/ssl_engine_mutex.c
index bbcd92ad..e915a163 100644
--- a/modules/ssl/ssl_engine_mutex.c
+++ b/modules/ssl/ssl_engine_mutex.c
@@ -30,43 +30,29 @@
#include "ssl_private.h"
-#ifdef AP_NEED_SET_MUTEX_PERMS
-#include "unixd.h"
-#endif
-
int ssl_mutex_init(server_rec *s, apr_pool_t *p)
{
SSLModConfigRec *mc = myModConfig(s);
apr_status_t rv;
- if (mc->nMutexMode == SSL_MUTEXMODE_NONE)
+ /* A mutex is only needed if a session cache is configured, and
+ * the provider used is not internally multi-process/thread
+ * safe. */
+ if (!mc->sesscache
+ || (mc->sesscache->flags & AP_SOCACHE_FLAG_NOTMPSAFE) == 0) {
return TRUE;
+ }
if (mc->pMutex) {
return TRUE;
}
- if ((rv = apr_global_mutex_create(&mc->pMutex, mc->szMutexFile,
- mc->nMutexMech, s->process->pool))
+
+ if ((rv = ap_global_mutex_create(&mc->pMutex, NULL, SSL_CACHE_MUTEX_TYPE,
+ NULL, s, s->process->pool, 0))
!= APR_SUCCESS) {
- if (mc->szMutexFile)
- ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
- "Cannot create SSLMutex with file `%s'",
- mc->szMutexFile);
- else
- ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
- "Cannot create SSLMutex");
return FALSE;
}
-#ifdef AP_NEED_SET_MUTEX_PERMS
- rv = unixd_set_global_mutex_perms(mc->pMutex);
- if (rv != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
- "Could not set permissions on ssl_mutex; check User "
- "and Group directives");
- return FALSE;
- }
-#endif
return TRUE;
}
@@ -74,19 +60,24 @@ int ssl_mutex_reinit(server_rec *s, apr_pool_t *p)
{
SSLModConfigRec *mc = myModConfig(s);
apr_status_t rv;
+ const char *lockfile;
- if (mc->nMutexMode == SSL_MUTEXMODE_NONE)
+ if (mc->pMutex == NULL || !mc->sesscache
+ || (mc->sesscache->flags & AP_SOCACHE_FLAG_NOTMPSAFE) == 0) {
return TRUE;
+ }
+ lockfile = apr_global_mutex_lockfile(mc->pMutex);
if ((rv = apr_global_mutex_child_init(&mc->pMutex,
- mc->szMutexFile, p)) != APR_SUCCESS) {
- if (mc->szMutexFile)
- ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
- "Cannot reinit SSLMutex with file `%s'",
- mc->szMutexFile);
+ lockfile,
+ p)) != APR_SUCCESS) {
+ if (lockfile)
+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(02024)
+ "Cannot reinit %s mutex with file `%s'",
+ SSL_CACHE_MUTEX_TYPE, lockfile);
else
- ap_log_error(APLOG_MARK, APLOG_WARNING, rv, s,
- "Cannot reinit SSLMutex");
+ ap_log_error(APLOG_MARK, APLOG_WARNING, rv, s, APLOGNO(02025)
+ "Cannot reinit %s mutex", SSL_CACHE_MUTEX_TYPE);
return FALSE;
}
return TRUE;
@@ -97,10 +88,8 @@ int ssl_mutex_on(server_rec *s)
SSLModConfigRec *mc = myModConfig(s);
apr_status_t rv;
- if (mc->nMutexMode == SSL_MUTEXMODE_NONE)
- return TRUE;
if ((rv = apr_global_mutex_lock(mc->pMutex)) != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, rv, s,
+ ap_log_error(APLOG_MARK, APLOG_WARNING, rv, s, APLOGNO(02026)
"Failed to acquire SSL session cache lock");
return FALSE;
}
@@ -112,10 +101,8 @@ int ssl_mutex_off(server_rec *s)
SSLModConfigRec *mc = myModConfig(s);
apr_status_t rv;
- if (mc->nMutexMode == SSL_MUTEXMODE_NONE)
- return TRUE;
if ((rv = apr_global_mutex_unlock(mc->pMutex)) != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, rv, s,
+ ap_log_error(APLOG_MARK, APLOG_WARNING, rv, s, APLOGNO(02027)
"Failed to release SSL session cache lock");
return FALSE;
}
diff --git a/modules/ssl/ssl_engine_ocsp.c b/modules/ssl/ssl_engine_ocsp.c
new file mode 100644
index 00000000..90da5c27
--- /dev/null
+++ b/modules/ssl/ssl_engine_ocsp.c
@@ -0,0 +1,297 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ssl_private.h"
+
+#ifndef OPENSSL_NO_OCSP
+#include "apr_base64.h"
+
+/* Return the responder URI specified in the given certificate, or
+ * NULL if none specified. */
+static const char *extract_responder_uri(X509 *cert, apr_pool_t *pool)
+{
+ STACK_OF(ACCESS_DESCRIPTION) *values;
+ char *result = NULL;
+ int j;
+
+ values = X509_get_ext_d2i(cert, NID_info_access, NULL, NULL);
+ if (!values) {
+ return NULL;
+ }
+
+ for (j = 0; j < sk_ACCESS_DESCRIPTION_num(values) && !result; j++) {
+ ACCESS_DESCRIPTION *value = sk_ACCESS_DESCRIPTION_value(values, j);
+
+ /* Name found in extension, and is a URI: */
+ if (OBJ_obj2nid(value->method) == NID_ad_OCSP
+ && value->location->type == GEN_URI) {
+ result = apr_pstrdup(pool,
+ (char *)value->location->d.uniformResourceIdentifier->data);
+ }
+ }
+
+ AUTHORITY_INFO_ACCESS_free(values);
+
+ return result;
+}
+
+/* Return the responder URI object which should be used in the given
+ * configuration for the given certificate, or NULL if none can be
+ * determined. */
+static apr_uri_t *determine_responder_uri(SSLSrvConfigRec *sc, X509 *cert,
+ conn_rec *c, apr_pool_t *p)
+{
+ apr_uri_t *u = apr_palloc(p, sizeof *u);
+ const char *s;
+ apr_status_t rv;
+
+ /* Use default responder URL if forced by configuration, else use
+ * certificate-specified responder, falling back to default if
+ * necessary and possible. */
+ if (sc->server->ocsp_force_default) {
+ s = sc->server->ocsp_responder;
+ }
+ else {
+ s = extract_responder_uri(cert, p);
+
+ if (s == NULL && sc->server->ocsp_responder) {
+ s = sc->server->ocsp_responder;
+ }
+ }
+
+ if (s == NULL) {
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(01918)
+ "no OCSP responder specified in certificate and "
+ "no default configured");
+ return NULL;
+ }
+
+ rv = apr_uri_parse(p, s, u);
+ if (rv || !u->hostname) {
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, c, APLOGNO(01919)
+ "failed to parse OCSP responder URI '%s'", s);
+ return NULL;
+ }
+
+ if (strcasecmp(u->scheme, "http") != 0) {
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, rv, c, APLOGNO(01920)
+ "cannot handle OCSP responder URI '%s'", s);
+ return NULL;
+ }
+
+ if (!u->port) {
+ u->port = apr_uri_port_of_scheme(u->scheme);
+ }
+
+ return u;
+}
+
+/* Create an OCSP request for the given certificate; returning the
+ * certificate ID in *certid and *issuer on success. Returns the
+ * request object on success, or NULL on error. */
+static OCSP_REQUEST *create_request(X509_STORE_CTX *ctx, X509 *cert,
+ OCSP_CERTID **certid,
+ server_rec *s, apr_pool_t *p)
+{
+ OCSP_REQUEST *req = OCSP_REQUEST_new();
+
+ *certid = OCSP_cert_to_id(NULL, cert, ctx->current_issuer);
+ if (!*certid || !OCSP_request_add0_id(req, *certid)) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01921)
+ "could not retrieve certificate id");
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s);
+ return NULL;
+ }
+
+ OCSP_request_add1_nonce(req, 0, -1);
+
+ return req;
+}
+
+/* Verify the OCSP status of given certificate. Returns
+ * V_OCSP_CERTSTATUS_* result code. */
+static int verify_ocsp_status(X509 *cert, X509_STORE_CTX *ctx, conn_rec *c,
+ SSLSrvConfigRec *sc, server_rec *s,
+ apr_pool_t *pool)
+{
+ int rc = V_OCSP_CERTSTATUS_GOOD;
+ OCSP_RESPONSE *response = NULL;
+ OCSP_BASICRESP *basicResponse = NULL;
+ OCSP_REQUEST *request = NULL;
+ OCSP_CERTID *certID = NULL;
+ apr_uri_t *ruri;
+
+ ruri = determine_responder_uri(sc, cert, c, pool);
+ if (!ruri) {
+ return V_OCSP_CERTSTATUS_UNKNOWN;
+ }
+
+ request = create_request(ctx, cert, &certID, s, pool);
+ if (request) {
+ apr_interval_time_t to = sc->server->ocsp_responder_timeout == UNSET ?
+ apr_time_from_sec(DEFAULT_OCSP_TIMEOUT) :
+ sc->server->ocsp_responder_timeout;
+ response = modssl_dispatch_ocsp_request(ruri, to, request, c, pool);
+ }
+
+ if (!request || !response) {
+ rc = V_OCSP_CERTSTATUS_UNKNOWN;
+ }
+
+ if (rc == V_OCSP_CERTSTATUS_GOOD) {
+ int r = OCSP_response_status(response);
+
+ if (r != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01922)
+ "OCSP response not successful: %d", rc);
+ rc = V_OCSP_CERTSTATUS_UNKNOWN;
+ }
+ }
+
+ if (rc == V_OCSP_CERTSTATUS_GOOD) {
+ basicResponse = OCSP_response_get1_basic(response);
+ if (!basicResponse) {
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(01923)
+ "could not retrieve OCSP basic response");
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s);
+ rc = V_OCSP_CERTSTATUS_UNKNOWN;
+ }
+ }
+
+ if (rc == V_OCSP_CERTSTATUS_GOOD) {
+ if (OCSP_check_nonce(request, basicResponse) != 1) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01924)
+ "Bad OCSP responder answer (bad nonce)");
+ rc = V_OCSP_CERTSTATUS_UNKNOWN;
+ }
+ }
+
+ if (rc == V_OCSP_CERTSTATUS_GOOD) {
+ /* TODO: allow flags configuration. */
+ if (OCSP_basic_verify(basicResponse, NULL, ctx->ctx, 0) != 1) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01925)
+ "failed to verify the OCSP response");
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s);
+ rc = V_OCSP_CERTSTATUS_UNKNOWN;
+ }
+ }
+
+ if (rc == V_OCSP_CERTSTATUS_GOOD) {
+ int reason = -1, status;
+ ASN1_GENERALIZEDTIME *thisup = NULL, *nextup = NULL;
+
+ rc = OCSP_resp_find_status(basicResponse, certID, &status,
+ &reason, NULL, &thisup, &nextup);
+ if (rc != 1) {
+ ssl_log_cxerror(SSLLOG_MARK, APLOG_ERR, 0, c, cert, APLOGNO(02272)
+ "failed to retrieve OCSP response status");
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s);
+ rc = V_OCSP_CERTSTATUS_UNKNOWN;
+ }
+ else {
+ rc = status;
+ }
+
+ /* Check whether the response is inside the defined validity
+ * period; otherwise fail. */
+ if (rc != V_OCSP_CERTSTATUS_UNKNOWN) {
+ long resptime_skew = sc->server->ocsp_resptime_skew == UNSET ?
+ DEFAULT_OCSP_MAX_SKEW : sc->server->ocsp_resptime_skew;
+ /* oscp_resp_maxage can be passed verbatim - UNSET (-1) means
+ * that responses can be of any age as long as nextup is in the
+ * future. */
+ int vrc = OCSP_check_validity(thisup, nextup, resptime_skew,
+ sc->server->ocsp_resp_maxage);
+ if (vrc != 1) {
+ ssl_log_cxerror(SSLLOG_MARK, APLOG_ERR, 0, c, cert, APLOGNO(02273)
+ "OCSP response outside validity period");
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s);
+ rc = V_OCSP_CERTSTATUS_UNKNOWN;
+ }
+ }
+
+ {
+ int level =
+ (status == V_OCSP_CERTSTATUS_GOOD) ? APLOG_INFO : APLOG_ERR;
+ const char *result =
+ status == V_OCSP_CERTSTATUS_GOOD ? "good" :
+ (status == V_OCSP_CERTSTATUS_REVOKED ? "revoked" : "unknown");
+
+ ssl_log_cxerror(SSLLOG_MARK, level, 0, c, cert,
+ "OCSP validation completed, "
+ "certificate status: %s (%d, %d)",
+ result, status, reason);
+ }
+ }
+
+ if (request) OCSP_REQUEST_free(request);
+ if (response) OCSP_RESPONSE_free(response);
+ if (basicResponse) OCSP_BASICRESP_free(basicResponse);
+ /* certID is freed when the request is freed */
+
+ return rc;
+}
+
+int modssl_verify_ocsp(X509_STORE_CTX *ctx, SSLSrvConfigRec *sc,
+ server_rec *s, conn_rec *c, apr_pool_t *pool)
+{
+ X509 *cert = X509_STORE_CTX_get_current_cert(ctx);
+ apr_pool_t *vpool;
+ int rv;
+
+ if (!cert) {
+ /* starting with OpenSSL 1.0, X509_STORE_CTX_get_current_cert()
+ * may yield NULL. Return early, but leave the ctx error as is. */
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
+ "No cert available to check with OCSP");
+ return 1;
+ }
+ else if (cert->valid && X509_check_issued(cert,cert) == X509_V_OK) {
+ /* don't do OCSP checking for valid self-issued certs */
+ ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
+ "Skipping OCSP check for valid self-issued cert");
+ X509_STORE_CTX_set_error(ctx, X509_V_OK);
+ return 1;
+ }
+
+ /* Create a temporary pool to constrain memory use (the passed-in
+ * pool may be e.g. a connection pool). */
+ apr_pool_create(&vpool, pool);
+
+ rv = verify_ocsp_status(cert, ctx, c, sc, s, vpool);
+
+ apr_pool_destroy(vpool);
+
+ /* Propagate the verification status back to the passed-in
+ * context. */
+ switch (rv) {
+ case V_OCSP_CERTSTATUS_GOOD:
+ X509_STORE_CTX_set_error(ctx, X509_V_OK);
+ break;
+
+ case V_OCSP_CERTSTATUS_REVOKED:
+ X509_STORE_CTX_set_error(ctx, X509_V_ERR_CERT_REVOKED);
+ break;
+
+ case V_OCSP_CERTSTATUS_UNKNOWN:
+ /* correct error code for application errors? */
+ X509_STORE_CTX_set_error(ctx, X509_V_ERR_APPLICATION_VERIFICATION);
+ break;
+ }
+
+ return rv == V_OCSP_CERTSTATUS_GOOD;
+}
+#endif /* HAVE_OCSP */
diff --git a/modules/ssl/ssl_engine_pphrase.c b/modules/ssl/ssl_engine_pphrase.c
index dc49eff6..b12cdacd 100644
--- a/modules/ssl/ssl_engine_pphrase.c
+++ b/modules/ssl/ssl_engine_pphrase.c
@@ -109,11 +109,7 @@ static apr_file_t *readtty = NULL;
*/
static server_rec *ssl_pphrase_server_rec = NULL;
-#ifdef SSLC_VERSION_NUMBER
-int ssl_pphrase_Handle_CB(char *, int, int);
-#else
int ssl_pphrase_Handle_CB(char *, int, int, void *);
-#endif
static char *pphrase_array_get(apr_array_header_t *arr, int idx)
{
@@ -132,6 +128,13 @@ static void pphrase_array_clear(apr_array_header_t *arr)
arr->nelts = 0;
}
+/* Abandon all hope, ye who read this code. Don't believe the name:
+ * "passphrase handling" is really a peripheral (if complex) concern;
+ * the core purpose of this function to load into memory all
+ * configured certs and key from files. The private key handling in
+ * here should be split out into a separate function for improved
+ * readability. The myCtxVarGet abomination can be thrown away with
+ * SSLC support, vastly simplifying the code. */
void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
{
SSLModConfigRec *mc = myModConfig(s);
@@ -157,9 +160,7 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
int i, j;
ssl_algo_t algoCert, algoKey, at;
char *an;
- char *cp;
apr_time_t pkey_mtime = 0;
- int isterm = 1;
apr_status_t rv;
/*
* Start with a fresh pass phrase array
@@ -173,43 +174,70 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
*/
for (pServ = s; pServ != NULL; pServ = pServ->next) {
sc = mySrvConfig(pServ);
-
- if (!sc->enabled)
+ cpVHostID = ssl_util_vhostid(p, pServ);
+ if (!sc->enabled) {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, pServ, APLOGNO(02199)
+ "SSL not enabled on vhost %s, skipping SSL setup",
+ cpVHostID);
continue;
+ }
- cpVHostID = ssl_util_vhostid(p, pServ);
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, pServ,
- "Loading certificate & private key of SSL-aware server");
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, pServ, APLOGNO(02200)
+ "Loading certificate & private key of SSL-aware server '%s'",
+ cpVHostID);
/*
* Read in server certificate(s): This is the easy part
* because this file isn't encrypted in any way.
*/
- if (sc->server->pks->cert_files[0] == NULL) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, pServ,
+ if (sc->server->pks->cert_files[0] == NULL
+ && sc->server->pkcs7 == NULL) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, pServ, APLOGNO(02240)
"Server should be SSL-aware but has no certificate "
"configured [Hint: SSLCertificateFile] (%s:%d)",
pServ->defn_name, pServ->defn_line_number);
ssl_die();
}
+
+ /* Bitmasks for all key algorithms configured for this server;
+ * initialize to zero. */
algoCert = SSL_ALGO_UNKNOWN;
algoKey = SSL_ALGO_UNKNOWN;
- for (i = 0, j = 0; i < SSL_AIDX_MAX && sc->server->pks->cert_files[i] != NULL; i++) {
- apr_cpystrn(szPath, sc->server->pks->cert_files[i], sizeof(szPath));
- if ((rv = exists_and_readable(szPath, p, NULL)) != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
- "Init: Can't open server certificate file %s",
+ /* Iterate through configured certificate files for this
+ * server. */
+ for (i = 0, j = 0; i < SSL_AIDX_MAX
+ && (sc->server->pks->cert_files[i] != NULL
+ || sc->server->pkcs7); i++) {
+ const char *key_id;
+ int using_cache = 0;
+
+ if (sc->server->pkcs7) {
+ STACK_OF(X509) *certs = ssl_read_pkcs7(pServ,
+ sc->server->pkcs7);
+ pX509Cert = sk_X509_value(certs, 0);
+ i = SSL_AIDX_MAX;
+ } else {
+ apr_cpystrn(szPath, sc->server->pks->cert_files[i],
+ sizeof(szPath));
+ if ((rv = exists_and_readable(szPath, p, NULL))
+ != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(02201)
+ "Init: Can't open server certificate file %s",
+ szPath);
+ ssl_die();
+ }
+ if ((pX509Cert = SSL_read_X509(szPath, NULL, NULL)) == NULL) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02241)
+ "Init: Unable to read server certificate from"
+ " file %s", szPath);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
+ ssl_die();
+ }
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(02202)
+ "Init: Read server certificate from '%s'",
szPath);
- ssl_die();
}
- if ((pX509Cert = SSL_read_X509(szPath, NULL, NULL)) == NULL) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
- "Init: Unable to read server certificate from file %s", szPath);
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
- ssl_die();
- }
-
/*
* check algorithm type of certificate and make
* sure only one certificate per type is used.
@@ -217,14 +245,19 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
at = ssl_util_algotypeof(pX509Cert, NULL);
an = ssl_util_algotypestr(at);
if (algoCert & at) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02242)
"Init: Multiple %s server certificates not "
"allowed", an);
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
ssl_die();
}
algoCert |= at;
+ /* Determine the hash key used for this (vhost, algo-type)
+ * pair used to index both the mc->tPrivateKey and
+ * mc->tPublicCert tables: */
+ key_id = asn1_table_vhost_key(mc, p, cpVHostID, an);
+
/*
* Insert the certificate into global module configuration to let it
* survive the processing between the 1st Apache API init round (where
@@ -232,9 +265,8 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
* certificate is actually used to configure mod_ssl's per-server
* configuration structures).
*/
- cp = asn1_table_vhost_key(mc, p, cpVHostID, an);
length = i2d_X509(pX509Cert, NULL);
- ucp = ssl_asn1_table_set(mc->tPublicCert, cp, length);
+ ucp = ssl_asn1_table_set(mc->tPublicCert, key_id, length);
(void)i2d_X509(pX509Cert, &ucp); /* 2nd arg increments */
/*
@@ -293,7 +325,7 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
*/
if ((rv = exists_and_readable(szPath, p,
&pkey_mtime)) != APR_SUCCESS ) {
- ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
+ ap_log_error(APLOG_MARK, APLOG_EMERG, rv, s, APLOGNO(02243)
"Init: Can't open server private key file "
"%s",szPath);
ssl_die();
@@ -320,22 +352,17 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
* are used to give a better idea as to what failed.
*/
if (pkey_mtime) {
- int i;
-
- for (i=0; i < SSL_AIDX_MAX; i++) {
- const char *key_id =
- ssl_asn1_table_keyfmt(p, cpVHostID, i);
- ssl_asn1_t *asn1 =
- ssl_asn1_table_get(mc->tPrivateKey, key_id);
-
- if (asn1 && (asn1->source_mtime == pkey_mtime)) {
- ap_log_error(APLOG_MARK, APLOG_INFO,
- 0, pServ,
- "%s reusing existing "
- "%s private key on restart",
- cpVHostID, ssl_asn1_keystr(i));
- return;
- }
+ ssl_asn1_t *asn1 =
+ ssl_asn1_table_get(mc->tPrivateKey, key_id);
+
+ if (asn1 && (asn1->source_mtime == pkey_mtime)) {
+ ap_log_error(APLOG_MARK, APLOG_INFO,
+ 0, pServ, APLOGNO(02244)
+ "%s reusing existing "
+ "%s private key on restart",
+ cpVHostID, ssl_asn1_keystr(i));
+ using_cache = 1;
+ break;
}
}
@@ -394,7 +421,7 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
}
#ifdef WIN32
if (sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02245)
"Init: SSLPassPhraseDialog builtin is not "
"supported on Win32 (key file "
"%s)", szPath);
@@ -407,19 +434,19 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
*/
if (cpPassPhraseCur == NULL) {
if (nPassPhraseDialogCur && pkey_mtime &&
- !(isterm = isatty(fileno(stdout)))) /* XXX: apr_isatty() */
+ !isatty(fileno(stdout))) /* XXX: apr_isatty() */
{
ap_log_error(APLOG_MARK, APLOG_ERR, 0,
- pServ,
+ pServ, APLOGNO(02246)
"Init: Unable to read pass phrase "
"[Hint: key introduced or changed "
"before restart?]");
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, pServ);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, pServ);
}
else {
ap_log_error(APLOG_MARK, APLOG_ERR, 0,
- pServ, "Init: Private key not found");
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, pServ);
+ pServ, APLOGNO(02203) "Init: Private key not found");
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, pServ);
}
if (writetty) {
apr_file_printf(writetty, "Apache:mod_ssl:Error: Private key not found.\n");
@@ -427,9 +454,10 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
}
}
else {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0,
- pServ, "Init: Pass phrase incorrect");
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, pServ);
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, pServ, APLOGNO(02204)
+ "Init: Pass phrase incorrect for key of %s",
+ cpVHostID);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, pServ);
if (writetty) {
apr_file_printf(writetty, "Apache:mod_ssl:Error: Pass phrase incorrect.\n");
@@ -439,12 +467,18 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
ssl_die();
}
+ /* If a cached private key was found, nothing more to do
+ * here; loop through to the next configured cert for this
+ * vhost. */
+ if (using_cache)
+ continue;
+
if (pPrivateKey == NULL) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02247)
"Init: Unable to read server private key from "
"file %s [Hint: Perhaps it is in a separate file? "
" See SSLCertificateKeyFile]", szPath);
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
ssl_die();
}
@@ -455,10 +489,10 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
at = ssl_util_algotypeof(NULL, pPrivateKey);
an = ssl_util_algotypestr(at);
if (algoKey & at) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02248)
"Init: Multiple %s server private keys not "
"allowed", an);
- ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_EMERG, s);
ssl_die();
}
algoKey |= at;
@@ -467,20 +501,20 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
* Log the type of reading
*/
if (nPassPhraseDialogCur == 0) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, pServ,
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, pServ, APLOGNO(02249)
"unencrypted %s private key - pass phrase not "
"required", an);
}
else {
if (cpPassPhraseCur != NULL) {
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
- pServ,
+ pServ, APLOGNO(02250)
"encrypted %s private key - pass phrase "
"requested", an);
}
else {
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0,
- pServ,
+ pServ, APLOGNO(02251)
"encrypted %s private key - pass phrase"
" reused", an);
}
@@ -501,14 +535,13 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
* because the SSL library uses static variables inside a
* RSA structure which do not survive DSO reloads!)
*/
- cp = asn1_table_vhost_key(mc, p, cpVHostID, an);
length = i2d_PrivateKey(pPrivateKey, NULL);
- ucp = ssl_asn1_table_set(mc->tPrivateKey, cp, length);
+ ucp = ssl_asn1_table_set(mc->tPrivateKey, key_id, length);
(void)i2d_PrivateKey(pPrivateKey, &ucp); /* 2nd arg increments */
if (nPassPhraseDialogCur != 0) {
/* remember mtime of encrypted keys */
- asn1 = ssl_asn1_table_get(mc->tPrivateKey, cp);
+ asn1 = ssl_asn1_table_get(mc->tPrivateKey, key_id);
asn1->source_mtime = pkey_mtime;
}
@@ -536,7 +569,7 @@ void ssl_pphrase_Handle(server_rec *s, apr_pool_t *p)
*/
if (aPassPhrase->nelts) {
pphrase_array_clear(aPassPhrase);
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(02205)
"Init: Wiped out the queried pass phrases from memory");
}
@@ -612,14 +645,8 @@ static int pipe_get_passwd_cb(char *buf, int length, char *prompt, int verify)
return 0;
}
-#ifdef SSLC_VERSION_NUMBER
-int ssl_pphrase_Handle_CB(char *buf, int bufsize, int verify)
-{
- void *srv = ssl_pphrase_server_rec;
-#else
int ssl_pphrase_Handle_CB(char *buf, int bufsize, int verify, void *srv)
{
-#endif
SSLModConfigRec *mc;
server_rec *s;
apr_pool_t *p;
@@ -674,12 +701,12 @@ int ssl_pphrase_Handle_CB(char *buf, int bufsize, int verify, void *srv)
if (sc->server->pphrase_dialog_type == SSL_PPTYPE_PIPE) {
if (!readtty) {
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01965)
"Init: Creating pass phrase dialog pipe child "
"'%s'", sc->server->pphrase_dialog_path);
if (ssl_pipe_child_create(p, sc->server->pphrase_dialog_path)
!= APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01966)
"Init: Failed to create pass phrase pipe '%s'",
sc->server->pphrase_dialog_path);
PEMerr(PEM_F_DEF_CALLBACK,PEM_R_PROBLEMS_GETTING_PASSWORD);
@@ -687,7 +714,7 @@ int ssl_pphrase_Handle_CB(char *buf, int bufsize, int verify, void *srv)
return (-1);
}
}
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01967)
"Init: Requesting pass phrase via piped dialog");
}
else { /* sc->server->pphrase_dialog_type == SSL_PPTYPE_BUILTIN */
@@ -704,7 +731,7 @@ int ssl_pphrase_Handle_CB(char *buf, int bufsize, int verify, void *srv)
*/
apr_file_open_stdout(&writetty, p);
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01968)
"Init: Requesting pass phrase via builtin terminal "
"dialog");
#endif
@@ -717,8 +744,8 @@ int ssl_pphrase_Handle_CB(char *buf, int bufsize, int verify, void *srv)
* something...
*/
if (*pnPassPhraseDialog == 1) {
- apr_file_printf(writetty, "%s mod_ssl/%s (Pass Phrase Dialog)\n",
- AP_SERVER_BASEVERSION, MOD_SSL_VERSION);
+ apr_file_printf(writetty, "%s mod_ssl (Pass Phrase Dialog)\n",
+ AP_SERVER_BASEVERSION);
apr_file_printf(writetty, "Some of your private key files are encrypted for security reasons.\n");
apr_file_printf(writetty, "In order to read them you have to provide the pass phrases.\n");
}
@@ -763,7 +790,7 @@ int ssl_pphrase_Handle_CB(char *buf, int bufsize, int verify, void *srv)
const char **argv = apr_palloc(p, sizeof(char *) * 4);
char *result;
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01969)
"Init: Requesting pass phrase from dialog filter "
"program (%s)", cmd);
@@ -783,7 +810,7 @@ int ssl_pphrase_Handle_CB(char *buf, int bufsize, int verify, void *srv)
*cppPassPhraseCur = apr_pstrdup(p, buf);
/*
- * And return it's length to OpenSSL...
+ * And return its length to OpenSSL...
*/
return (len);
}
diff --git a/modules/ssl/ssl_engine_rand.c b/modules/ssl/ssl_engine_rand.c
index a3c0fc5b..df25d8fd 100644
--- a/modules/ssl/ssl_engine_rand.c
+++ b/modules/ssl/ssl_engine_rand.c
@@ -45,19 +45,17 @@ int ssl_rand_seed(server_rec *s, apr_pool_t *p, ssl_rsctx_t nCtx, char *prefix)
ssl_randseed_t *pRandSeeds;
ssl_randseed_t *pRandSeed;
unsigned char stackdata[256];
- int nReq, nDone;
+ int nDone;
apr_file_t *fp;
int i, n, l;
mc = myModConfig(s);
- nReq = 0;
nDone = 0;
apRandSeed = mc->aRandSeed;
pRandSeeds = (ssl_randseed_t *)apRandSeed->elts;
for (i = 0; i < apRandSeed->nelts; i++) {
pRandSeed = &pRandSeeds[i];
if (pRandSeed->nCtx == nCtx) {
- nReq += pRandSeed->nBytes;
if (pRandSeed->nSrc == SSL_RSSRC_FILE) {
/*
* seed in contents of an external file
@@ -83,7 +81,6 @@ int ssl_rand_seed(server_rec *s, apr_pool_t *p, ssl_rsctx_t nCtx, char *prefix)
nDone += ssl_rand_feedfp(p, fp, pRandSeed->nBytes);
ssl_util_ppclose(s, p, fp);
}
-#ifdef HAVE_SSL_RAND_EGD
else if (pRandSeed->nSrc == SSL_RSSRC_EGD) {
/*
* seed in contents provided by the external
@@ -93,7 +90,6 @@ int ssl_rand_seed(server_rec *s, apr_pool_t *p, ssl_rsctx_t nCtx, char *prefix)
continue;
nDone += n;
}
-#endif
else if (pRandSeed->nSrc == SSL_RSSRC_BUILTIN) {
struct {
time_t t;
@@ -124,11 +120,11 @@ int ssl_rand_seed(server_rec *s, apr_pool_t *p, ssl_rsctx_t nCtx, char *prefix)
}
}
}
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_TRACE2, 0, s,
"%sSeeding PRNG with %d bytes of entropy", prefix, nDone);
if (RAND_status() == 0)
- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(01990)
"%sPRNG still contains insufficient entropy!", prefix);
return nDone;
diff --git a/modules/ssl/ssl_engine_vars.c b/modules/ssl/ssl_engine_vars.c
index 83cff2c1..3815cd43 100644
--- a/modules/ssl/ssl_engine_vars.c
+++ b/modules/ssl/ssl_engine_vars.c
@@ -29,6 +29,7 @@
-- Unknown */
#include "ssl_private.h"
#include "mod_ssl.h"
+#include "ap_expr.h"
#include "apr_time.h"
@@ -38,11 +39,11 @@
** _________________________________________________________________
*/
-static char *ssl_var_lookup_ssl(apr_pool_t *p, conn_rec *c, char *var);
-static char *ssl_var_lookup_ssl_cert(apr_pool_t *p, X509 *xs, char *var);
+static char *ssl_var_lookup_ssl(apr_pool_t *p, conn_rec *c, request_rec *r, char *var);
+static char *ssl_var_lookup_ssl_cert(apr_pool_t *p, request_rec *r, X509 *xs, char *var);
static char *ssl_var_lookup_ssl_cert_dn(apr_pool_t *p, X509_NAME *xsname, char *var);
-static char *ssl_var_lookup_ssl_cert_valid(apr_pool_t *p, ASN1_UTCTIME *tm);
-static char *ssl_var_lookup_ssl_cert_remain(apr_pool_t *p, ASN1_UTCTIME *tm);
+static char *ssl_var_lookup_ssl_cert_valid(apr_pool_t *p, ASN1_TIME *tm);
+static char *ssl_var_lookup_ssl_cert_remain(apr_pool_t *p, ASN1_TIME *tm);
static char *ssl_var_lookup_ssl_cert_serial(apr_pool_t *p, X509 *xs);
static char *ssl_var_lookup_ssl_cert_chain(apr_pool_t *p, STACK_OF(X509) *sk, char *var);
static char *ssl_var_lookup_ssl_cert_PEM(apr_pool_t *p, X509 *xs);
@@ -58,17 +59,56 @@ static int ssl_is_https(conn_rec *c)
return sslconn && sslconn->ssl;
}
-static const char var_interface[] = "mod_ssl/" MOD_SSL_VERSION;
+static const char var_interface[] = "mod_ssl/" AP_SERVER_BASEREVISION;
static char var_library_interface[] = SSL_LIBRARY_TEXT;
static char *var_library = NULL;
+static apr_array_header_t *expr_peer_ext_list_fn(ap_expr_eval_ctx_t *ctx,
+ const void *dummy,
+ const char *arg)
+{
+ return ssl_ext_list(ctx->p, ctx->c, 1, arg);
+}
+
+static const char *expr_var_fn(ap_expr_eval_ctx_t *ctx, const void *data)
+{
+ char *var = (char *)data;
+ return ssl_var_lookup_ssl(ctx->p, ctx->c, ctx->r, var);
+}
+
+static int ssl_expr_lookup(ap_expr_lookup_parms *parms)
+{
+ switch (parms->type) {
+ case AP_EXPR_FUNC_VAR:
+ /* for now, we just handle everything that starts with SSL_, but
+ * register our hook as APR_HOOK_LAST
+ * XXX: This can be optimized
+ */
+ if (strcEQn(parms->name, "SSL_", 4)) {
+ *parms->func = expr_var_fn;
+ *parms->data = parms->name + 4;
+ return OK;
+ }
+ break;
+ case AP_EXPR_FUNC_LIST:
+ if (strcEQ(parms->name, "PeerExtList")) {
+ *parms->func = expr_peer_ext_list_fn;
+ *parms->data = "PeerExtList";
+ return OK;
+ }
+ break;
+ }
+ return DECLINED;
+}
+
+
void ssl_var_register(apr_pool_t *p)
{
char *cp, *cp2;
APR_REGISTER_OPTIONAL_FN(ssl_is_https);
APR_REGISTER_OPTIONAL_FN(ssl_var_lookup);
- APR_REGISTER_OPTIONAL_FN(ssl_ext_lookup);
+ APR_REGISTER_OPTIONAL_FN(ssl_ext_list);
/* Perform once-per-process library version determination: */
var_library = apr_pstrdup(p, SSL_LIBRARY_DYNTEXT);
@@ -84,6 +124,8 @@ void ssl_var_register(apr_pool_t *p)
if ((cp2 = strchr(cp, ' ')) != NULL)
*cp2 = NUL;
}
+
+ ap_hook_expr_lookup(ssl_expr_lookup, NULL, NULL, APR_HOOK_MIDDLE);
}
/* This function must remain safe to use for a non-SSL connection. */
@@ -145,6 +187,8 @@ char *ssl_var_lookup(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r,
result = r->uri;
else if (strcEQ(var, "REQUEST_FILENAME"))
result = r->filename;
+ else if (strcEQ(var, "REMOTE_ADDR"))
+ result = r->useragent_ip;
else if (strcEQ(var, "REMOTE_HOST"))
result = ap_get_remote_host(r->connection, r->per_dir_config,
REMOTE_NAME, NULL);
@@ -161,7 +205,7 @@ char *ssl_var_lookup(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r,
if (strcEQ(var, "SERVER_ADMIN"))
result = r->server->server_admin;
else if (strcEQ(var, "SERVER_NAME"))
- result = ap_get_server_name(r);
+ result = ap_get_server_name_for_url(r);
else if (strcEQ(var, "SERVER_PORT"))
result = apr_psprintf(p, "%u", ap_get_server_port(r));
else if (strcEQ(var, "SERVER_PROTOCOL"))
@@ -183,6 +227,11 @@ char *ssl_var_lookup(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r,
result = r->ap_auth_type;
else if (strcEQ(var, "THE_REQUEST"))
result = r->the_request;
+ else if (strlen(var) > 4 && strcEQn(var, "ENV:", 4)) {
+ result = apr_table_get(r->notes, var+4);
+ if (result == NULL)
+ result = apr_table_get(r->subprocess_env, var+4);
+ }
break;
}
}
@@ -194,9 +243,7 @@ char *ssl_var_lookup(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r,
SSLConnRec *sslconn = myConnConfig(c);
if (strlen(var) > 4 && strcEQn(var, "SSL_", 4)
&& sslconn && sslconn->ssl)
- result = ssl_var_lookup_ssl(p, c, var+4);
- else if (strcEQ(var, "REMOTE_ADDR"))
- result = c->remote_ip;
+ result = ssl_var_lookup_ssl(p, c, r, var+4);
else if (strcEQ(var, "HTTPS")) {
if (sslconn && sslconn->ssl)
result = "on";
@@ -255,11 +302,7 @@ char *ssl_var_lookup(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r,
}
/* all other env-variables from the parent Apache process */
else if (strlen(var) > 4 && strcEQn(var, "ENV:", 4)) {
- result = apr_table_get(r->notes, var+4);
- if (result == NULL)
- result = apr_table_get(r->subprocess_env, var+4);
- if (result == NULL)
- result = getenv(var+4);
+ result = getenv(var+4);
}
}
@@ -270,7 +313,8 @@ char *ssl_var_lookup(apr_pool_t *p, server_rec *s, conn_rec *c, request_rec *r,
return (char *)result;
}
-static char *ssl_var_lookup_ssl(apr_pool_t *p, conn_rec *c, char *var)
+static char *ssl_var_lookup_ssl(apr_pool_t *p, conn_rec *c, request_rec *r,
+ char *var)
{
SSLConnRec *sslconn = myConnConfig(c);
char *result;
@@ -292,11 +336,17 @@ static char *ssl_var_lookup_ssl(apr_pool_t *p, conn_rec *c, char *var)
SSL_SESSION *pSession = SSL_get_session(ssl);
if (pSession) {
result = apr_pstrdup(p, SSL_SESSION_id2sz(
- SSL_SESSION_get_session_id(pSession),
- SSL_SESSION_get_session_id_length(pSession),
+ pSession->session_id,
+ pSession->session_id_length,
buf, sizeof(buf)));
}
}
+ else if(ssl != NULL && strcEQ(var, "SESSION_RESUMED")) {
+ if (SSL_session_reused(ssl) == 1)
+ result = "Resumed";
+ else
+ result = "Initial";
+ }
else if (ssl != NULL && strlen(var) >= 6 && strcEQn(var, "CIPHER", 6)) {
result = ssl_var_lookup_ssl_cipher(p, c, var+6);
}
@@ -309,13 +359,17 @@ static char *ssl_var_lookup_ssl(apr_pool_t *p, conn_rec *c, char *var)
}
else if (ssl != NULL && strlen(var) > 7 && strcEQn(var, "CLIENT_", 7)) {
if ((xs = SSL_get_peer_certificate(ssl)) != NULL) {
- result = ssl_var_lookup_ssl_cert(p, xs, var+7);
+ result = ssl_var_lookup_ssl_cert(p, r, xs, var+7);
X509_free(xs);
}
}
else if (ssl != NULL && strlen(var) > 7 && strcEQn(var, "SERVER_", 7)) {
- if ((xs = SSL_get_certificate(ssl)) != NULL)
- result = ssl_var_lookup_ssl_cert(p, xs, var+7);
+ if ((xs = SSL_get_certificate(ssl)) != NULL) {
+ result = ssl_var_lookup_ssl_cert(p, r, xs, var+7);
+ /* SSL_get_certificate is different from SSL_get_peer_certificate.
+ * No need to X509_free(xs).
+ */
+ }
}
else if (ssl != NULL && strcEQ(var, "COMPRESS_METHOD")) {
result = ssl_var_lookup_ssl_compress_meth(ssl);
@@ -332,18 +386,51 @@ static char *ssl_var_lookup_ssl(apr_pool_t *p, conn_rec *c, char *var)
flag = SSL_get_secure_renegotiation_support(ssl);
#endif
result = apr_pstrdup(p, flag ? "true" : "false");
- }
+ }
return result;
}
-static char *ssl_var_lookup_ssl_cert(apr_pool_t *p, X509 *xs, char *var)
+static char *ssl_var_lookup_ssl_cert_dn_oneline(apr_pool_t *p, request_rec *r,
+ X509_NAME *xsname)
+{
+ char *result = NULL;
+ SSLDirConfigRec *dc;
+ int legacy_format = 0;
+ if (r) {
+ dc = myDirConfig(r);
+ legacy_format = dc->nOptions & SSL_OPT_LEGACYDNFORMAT;
+ }
+ if (legacy_format) {
+ char *cp = X509_NAME_oneline(xsname, NULL, 0);
+ result = apr_pstrdup(p, cp);
+ OPENSSL_free(cp);
+ }
+ else {
+ BIO* bio;
+ int n;
+ unsigned long flags = XN_FLAG_RFC2253 & ~ASN1_STRFLGS_ESC_MSB;
+ if ((bio = BIO_new(BIO_s_mem())) == NULL)
+ return NULL;
+ X509_NAME_print_ex(bio, xsname, 0, flags);
+ n = BIO_pending(bio);
+ if (n > 0) {
+ result = apr_palloc(p, n+1);
+ n = BIO_read(bio, result, n);
+ result[n] = NUL;
+ }
+ BIO_free(bio);
+ }
+ return result;
+}
+
+static char *ssl_var_lookup_ssl_cert(apr_pool_t *p, request_rec *r, X509 *xs,
+ char *var)
{
char *result;
BOOL resdup;
X509_NAME *xsname;
int nid;
- char *cp;
result = NULL;
resdup = TRUE;
@@ -365,38 +452,34 @@ static char *ssl_var_lookup_ssl_cert(apr_pool_t *p, X509 *xs, char *var)
result = ssl_var_lookup_ssl_cert_remain(p, X509_get_notAfter(xs));
resdup = FALSE;
}
- else if (strcEQ(var, "S_DN")) {
- xsname = X509_get_subject_name(xs);
- cp = X509_NAME_oneline(xsname, NULL, 0);
- result = apr_pstrdup(p, cp);
- modssl_free(cp);
- resdup = FALSE;
- }
- else if (strlen(var) > 5 && strcEQn(var, "S_DN_", 5)) {
- xsname = X509_get_subject_name(xs);
- result = ssl_var_lookup_ssl_cert_dn(p, xsname, var+5);
- resdup = FALSE;
- }
- else if (strcEQ(var, "I_DN")) {
- xsname = X509_get_issuer_name(xs);
- cp = X509_NAME_oneline(xsname, NULL, 0);
- result = apr_pstrdup(p, cp);
- modssl_free(cp);
+ else if (*var && strcEQ(var+1, "_DN")) {
+ if (*var == 'S')
+ xsname = X509_get_subject_name(xs);
+ else if (*var == 'I')
+ xsname = X509_get_issuer_name(xs);
+ else
+ return NULL;
+ result = ssl_var_lookup_ssl_cert_dn_oneline(p, r, xsname);
resdup = FALSE;
}
- else if (strlen(var) > 5 && strcEQn(var, "I_DN_", 5)) {
- xsname = X509_get_issuer_name(xs);
+ else if (strlen(var) > 5 && strcEQn(var+1, "_DN_", 4)) {
+ if (*var == 'S')
+ xsname = X509_get_subject_name(xs);
+ else if (*var == 'I')
+ xsname = X509_get_issuer_name(xs);
+ else
+ return NULL;
result = ssl_var_lookup_ssl_cert_dn(p, xsname, var+5);
resdup = FALSE;
}
else if (strcEQ(var, "A_SIG")) {
- nid = OBJ_obj2nid((ASN1_OBJECT *)X509_get_signature_algorithm(xs));
+ nid = OBJ_obj2nid((ASN1_OBJECT *)(xs->cert_info->signature->algorithm));
result = apr_pstrdup(p,
(nid == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(nid));
resdup = FALSE;
}
else if (strcEQ(var, "A_KEY")) {
- nid = OBJ_obj2nid((ASN1_OBJECT *)X509_get_key_algorithm(xs));
+ nid = OBJ_obj2nid((ASN1_OBJECT *)(xs->cert_info->key->algor->algorithm));
result = apr_pstrdup(p,
(nid == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(nid));
resdup = FALSE;
@@ -431,7 +514,7 @@ static const struct {
{ "S", NID_surname, 1 },
{ "D", NID_description, 1 },
#ifdef NID_userId
- { "UID", NID_x500UniqueIdentifier, 1 },
+ { "UID", NID_userId, 1 },
#endif
{ "Email", NID_pkcs9_emailAddress, 1 },
{ NULL, 0, 0 }
@@ -459,21 +542,15 @@ static char *ssl_var_lookup_ssl_cert_dn(apr_pool_t *p, X509_NAME *xsname, char *
if (strEQn(var, ssl_var_lookup_ssl_cert_dn_rec[i].name, varlen)
&& strlen(ssl_var_lookup_ssl_cert_dn_rec[i].name) == varlen) {
for (j = 0; j < sk_X509_NAME_ENTRY_num((STACK_OF(X509_NAME_ENTRY) *)
- X509_NAME_get_entries(xsname));
+ xsname->entries);
j++) {
xsne = sk_X509_NAME_ENTRY_value((STACK_OF(X509_NAME_ENTRY) *)
- X509_NAME_get_entries(xsname), j);
+ xsname->entries, j);
n =OBJ_obj2nid((ASN1_OBJECT *)X509_NAME_ENTRY_get_object(xsne));
if (n == ssl_var_lookup_ssl_cert_dn_rec[i].nid && idx-- == 0) {
- unsigned char *data = X509_NAME_ENTRY_get_data_ptr(xsne);
- /* cast needed from unsigned char to char */
- result = apr_pstrmemdup(p, (char *)data,
- X509_NAME_ENTRY_get_data_len(xsne));
-#if APR_CHARSET_EBCDIC
- ap_xlate_proto_from_ascii(result, X509_NAME_ENTRY_get_data_len(xsne));
-#endif /* APR_CHARSET_EBCDIC */
+ result = SSL_X509_NAME_ENTRY_to_string(p, xsne);
break;
}
}
@@ -483,7 +560,7 @@ static char *ssl_var_lookup_ssl_cert_dn(apr_pool_t *p, X509_NAME *xsname, char *
return result;
}
-static char *ssl_var_lookup_ssl_cert_valid(apr_pool_t *p, ASN1_UTCTIME *tm)
+static char *ssl_var_lookup_ssl_cert_valid(apr_pool_t *p, ASN1_TIME *tm)
{
char *result;
BIO* bio;
@@ -491,7 +568,7 @@ static char *ssl_var_lookup_ssl_cert_valid(apr_pool_t *p, ASN1_UTCTIME *tm)
if ((bio = BIO_new(BIO_s_mem())) == NULL)
return NULL;
- ASN1_UTCTIME_print(bio, tm);
+ ASN1_TIME_print(bio, tm);
n = BIO_pending(bio);
result = apr_pcalloc(p, n+1);
n = BIO_read(bio, result, n);
@@ -504,27 +581,36 @@ static char *ssl_var_lookup_ssl_cert_valid(apr_pool_t *p, ASN1_UTCTIME *tm)
/* Return a string giving the number of days remaining until 'tm', or
* "0" if this can't be determined. */
-static char *ssl_var_lookup_ssl_cert_remain(apr_pool_t *p, ASN1_UTCTIME *tm)
+static char *ssl_var_lookup_ssl_cert_remain(apr_pool_t *p, ASN1_TIME *tm)
{
apr_time_t then, now = apr_time_now();
apr_time_exp_t exp = {0};
long diff;
+ unsigned char *dp;
- /* Fail if the time isn't a valid ASN.1 UTCTIME; RFC3280 mandates
+ /* Fail if the time isn't a valid ASN.1 TIME; RFC3280 mandates
* that the seconds digits are present even though ASN.1
* doesn't. */
- if (tm->length < 11 || !ASN1_UTCTIME_check(tm)) {
+ if ((tm->type == V_ASN1_UTCTIME && tm->length < 11) ||
+ (tm->type == V_ASN1_GENERALIZEDTIME && tm->length < 13) ||
+ !ASN1_TIME_check(tm)) {
return apr_pstrdup(p, "0");
}
- exp.tm_year = DIGIT2NUM(tm->data);
- exp.tm_mon = DIGIT2NUM(tm->data + 2) - 1;
- exp.tm_mday = DIGIT2NUM(tm->data + 4) + 1;
- exp.tm_hour = DIGIT2NUM(tm->data + 6);
- exp.tm_min = DIGIT2NUM(tm->data + 8);
- exp.tm_sec = DIGIT2NUM(tm->data + 10);
+ if (tm->type == V_ASN1_UTCTIME) {
+ exp.tm_year = DIGIT2NUM(tm->data);
+ if (exp.tm_year <= 50) exp.tm_year += 100;
+ dp = tm->data + 2;
+ } else {
+ exp.tm_year = DIGIT2NUM(tm->data) * 100 + DIGIT2NUM(tm->data + 2) - 1900;
+ dp = tm->data + 4;
+ }
- if (exp.tm_year <= 50) exp.tm_year += 100;
+ exp.tm_mon = DIGIT2NUM(dp) - 1;
+ exp.tm_mday = DIGIT2NUM(dp + 2) + 1;
+ exp.tm_hour = DIGIT2NUM(dp + 4);
+ exp.tm_min = DIGIT2NUM(dp + 6);
+ exp.tm_sec = DIGIT2NUM(dp + 8);
if (apr_time_exp_gmt_get(&then, &exp) != APR_SUCCESS) {
return apr_pstrdup(p, "0");
@@ -616,7 +702,8 @@ static char *ssl_var_lookup_ssl_cert_verify(apr_pool_t *p, conn_rec *c)
result = "GENEROUS";
else
/* client verification failed */
- result = apr_psprintf(p, "FAILED:%s", verr);
+ result = apr_psprintf(p, "FAILED:%s",
+ verr ? verr : X509_verify_cert_error_string(vrc));
if (xs)
X509_free(xs);
@@ -685,14 +772,14 @@ static char *ssl_var_lookup_ssl_version(apr_pool_t *p, char *var)
/* Add each RDN in 'xn' to the table 't' where the NID is present in
* 'nids', using key prefix 'pfx'. */
-static void extract_dn(apr_table_t *t, apr_hash_t *nids, const char *pfx,
+static void extract_dn(apr_table_t *t, apr_hash_t *nids, const char *pfx,
X509_NAME *xn, apr_pool_t *p)
{
- STACK_OF(X509_NAME_ENTRY) *ents = X509_NAME_get_entries(xn);
+ STACK_OF(X509_NAME_ENTRY) *ents = xn->entries;
X509_NAME_ENTRY *xsne;
apr_hash_t *count;
int i, nid;
-
+
/* Hash of (int) NID -> (int *) counter to count each time an RDN
* with the given NID has been seen. */
count = apr_hash_make(p);
@@ -709,7 +796,6 @@ static void extract_dn(apr_table_t *t, apr_hash_t *nids, const char *pfx,
tag = apr_hash_get(nids, &nid, sizeof nid);
if (tag) {
- unsigned char *data = X509_NAME_ENTRY_get_data_ptr(xsne);
const char *key;
int *dup;
char *value;
@@ -726,13 +812,7 @@ static void extract_dn(apr_table_t *t, apr_hash_t *nids, const char *pfx,
apr_hash_set(count, &nid, sizeof nid, dup);
key = apr_pstrcat(p, pfx, tag, NULL);
}
-
- /* cast needed from 'unsigned char *' to 'char *' */
- value = apr_pstrmemdup(p, (char *)data,
- X509_NAME_ENTRY_get_data_len(xsne));
-#if APR_CHARSET_EBCDIC
- ap_xlate_proto_from_ascii(value, X509_NAME_ENTRY_get_data_len(xsne));
-#endif /* APR_CHARSET_EBCDIC */
+ value = SSL_X509_NAME_ENTRY_to_string(p, xsne);
apr_table_setn(t, key, value);
}
}
@@ -754,7 +834,7 @@ void modssl_var_extract_dns(apr_table_t *t, SSL *ssl, apr_pool_t *p)
ssl_var_lookup_ssl_cert_dn_rec[n].name);
}
}
-
+
/* Extract the server cert DNS -- note that the refcount does NOT
* increase: */
xs = SSL_get_certificate(ssl);
@@ -762,7 +842,7 @@ void modssl_var_extract_dns(apr_table_t *t, SSL *ssl, apr_pool_t *p)
extract_dn(t, nids, "SSL_SERVER_S_DN_", X509_get_subject_name(xs), p);
extract_dn(t, nids, "SSL_SERVER_I_DN_", X509_get_issuer_name(xs), p);
}
-
+
/* Extract the client cert DNs -- note that the refcount DOES
* increase: */
xs = SSL_get_peer_certificate(ssl);
@@ -773,23 +853,50 @@ void modssl_var_extract_dns(apr_table_t *t, SSL *ssl, apr_pool_t *p)
}
}
-const char *ssl_ext_lookup(apr_pool_t *p, conn_rec *c, int peer,
- const char *oidnum)
+/* For an extension type which OpenSSL does not recognize, attempt to
+ * parse the extension type as a primitive string. This will fail for
+ * any structured extension type per the docs. Returns non-zero on
+ * success and writes the string to the given bio. */
+static int dump_extn_value(BIO *bio, ASN1_OCTET_STRING *str)
+{
+ MODSSL_D2I_ASN1_type_bytes_CONST unsigned char *pp = str->data;
+ ASN1_STRING *ret = ASN1_STRING_new();
+ int rv = 0;
+
+ /* This allows UTF8String, IA5String, VisibleString, or BMPString;
+ * conversion to UTF-8 is forced. */
+ if (d2i_DISPLAYTEXT(&ret, &pp, str->length)) {
+ ASN1_STRING_print_ex(bio, ret, ASN1_STRFLGS_UTF8_CONVERT);
+ rv = 1;
+ }
+
+ ASN1_STRING_free(ret);
+ return rv;
+}
+
+apr_array_header_t *ssl_ext_list(apr_pool_t *p, conn_rec *c, int peer,
+ const char *extension)
{
SSLConnRec *sslconn = myConnConfig(c);
- SSL *ssl;
+ SSL *ssl = NULL;
+ apr_array_header_t *array = NULL;
X509 *xs = NULL;
- ASN1_OBJECT *oid;
+ ASN1_OBJECT *oid = NULL;
int count = 0, j;
- char *result = NULL;
- if (!sslconn || !sslconn->ssl) {
+ if (!sslconn || !sslconn->ssl || !extension) {
return NULL;
}
ssl = sslconn->ssl;
- oid = OBJ_txt2obj(oidnum, 1);
+ /* We accept the "extension" string to be converted as
+ * a long name (nsComment), short name (DN) or
+ * numeric OID (1.2.3.4).
+ */
+ oid = OBJ_txt2obj(extension, 0);
if (!oid) {
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(01970)
+ "could not parse OID '%s'", extension);
ERR_clear_error();
return NULL;
}
@@ -800,38 +907,54 @@ const char *ssl_ext_lookup(apr_pool_t *p, conn_rec *c, int peer,
}
count = X509_get_ext_count(xs);
-
+ /* Create an array large enough to accomodate every extension. This is
+ * likely overkill, but safe.
+ */
+ array = apr_array_make(p, count, sizeof(char *));
for (j = 0; j < count; j++) {
X509_EXTENSION *ext = X509_get_ext(xs, j);
if (OBJ_cmp(ext->object, oid) == 0) {
BIO *bio = BIO_new(BIO_s_mem());
- if (X509V3_EXT_print(bio, ext, 0, 0) == 1) {
+ /* We want to obtain a string representation of the extensions
+ * value and add it to the array we're building.
+ * X509V3_EXT_print() doesn't know about all the possible
+ * data types, but the value is stored as an ASN1_OCTET_STRING
+ * allowing us a fallback in case of X509V3_EXT_print
+ * not knowing how to handle the data.
+ */
+ if (X509V3_EXT_print(bio, ext, 0, 0) == 1 ||
+ dump_extn_value(bio, X509_EXTENSION_get_data(ext)) == 1) {
BUF_MEM *buf;
-
+ char **ptr = apr_array_push(array);
BIO_get_mem_ptr(bio, &buf);
- result = apr_pstrmemdup(p, buf->data, buf->length);
+ *ptr = apr_pstrmemdup(p, buf->data, buf->length);
+ } else {
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(01971)
+ "Found an extension '%s', but failed to "
+ "create a string from it", extension);
}
-
BIO_vfree(bio);
- break;
}
}
+ if (array->nelts == 0)
+ array = NULL;
+
if (peer) {
/* only SSL_get_peer_certificate raises the refcount */
X509_free(xs);
}
+ ASN1_OBJECT_free(oid);
ERR_clear_error();
- return result;
+ return array;
}
static char *ssl_var_lookup_ssl_compress_meth(SSL *ssl)
{
char *result = "NULL";
-#ifdef OPENSSL_VERSION_NUMBER
#if (OPENSSL_VERSION_NUMBER >= 0x00908000)
SSL_SESSION *pSession = SSL_get_session(ssl);
@@ -857,7 +980,6 @@ static char *ssl_var_lookup_ssl_compress_meth(SSL *ssl)
}
}
#endif
-#endif
return result;
}
@@ -932,3 +1054,4 @@ static const char *ssl_var_log_handler_x(request_rec *r, char *a)
return result;
}
+
diff --git a/modules/ssl/ssl_expr.c b/modules/ssl/ssl_expr.c
deleted file mode 100644
index da57e228..00000000
--- a/modules/ssl/ssl_expr.c
+++ /dev/null
@@ -1,82 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* _ _
- * _ __ ___ ___ __| | ___ ___| | mod_ssl
- * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL
- * | | | | | | (_) | (_| | \__ \__ \ |
- * |_| |_| |_|\___/ \__,_|___|___/___/_|
- * |_____|
- * ssl_expr.c
- * Expression Handling
- */
- /* ``It is hard to fly with
- the eagles when you work
- with the turkeys.''
- -- Unknown */
-#include "ssl_private.h"
-
-/* _________________________________________________________________
-**
-** Expression Handling
-** _________________________________________________________________
-*/
-
-ssl_expr_info_type ssl_expr_info;
-char *ssl_expr_error;
-
-ssl_expr *ssl_expr_comp(apr_pool_t *p, char *expr)
-{
- ssl_expr_info.pool = p;
- ssl_expr_info.inputbuf = expr;
- ssl_expr_info.inputlen = strlen(expr);
- ssl_expr_info.inputptr = ssl_expr_info.inputbuf;
- ssl_expr_info.expr = FALSE;
-
- ssl_expr_error = NULL;
- if (ssl_expr_yyparse())
- return NULL;
- return ssl_expr_info.expr;
-}
-
-char *ssl_expr_get_error(void)
-{
- if (ssl_expr_error == NULL)
- return "";
- return ssl_expr_error;
-}
-
-ssl_expr *ssl_expr_make(ssl_expr_node_op op, void *a1, void *a2)
-{
- ssl_expr *node;
-
- node = (ssl_expr *)apr_palloc(ssl_expr_info.pool, sizeof(ssl_expr));
- node->node_op = op;
- node->node_arg1 = (char *)a1;
- node->node_arg2 = (char *)a2;
- return node;
-}
-
-int ssl_expr_exec(request_rec *r, ssl_expr *expr)
-{
- BOOL rc;
-
- rc = ssl_expr_eval(r, expr);
- if (ssl_expr_error != NULL)
- return (-1);
- else
- return (rc ? 1 : 0);
-}
diff --git a/modules/ssl/ssl_expr.h b/modules/ssl/ssl_expr.h
deleted file mode 100644
index 0a1526db..00000000
--- a/modules/ssl/ssl_expr.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/**
- * @verbatim
- _ _
- _ __ ___ ___ __| | ___ ___| | mod_ssl
- | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL
- | | | | | | (_) | (_| | \__ \__ \ |
- |_| |_| |_|\___/ \__,_|___|___/___/_|
- |_____|
- @endverbatim
- * @file ssl_expr.h
- * @brief Expression Handling (Header).
- * ``May all your PUSHes be POPed.''
- *
- * @defgroup MOD_SSL_EXPR Expression Handling
- * @ingroup MOD_SSL
- * @{
- */
-
-#ifndef __SSL_EXPR_H__
-#define __SSL_EXPR_H__
-
-#ifndef FALSE
-#define FALSE 0
-#endif
-
-#ifndef TRUE
-#define TRUE !FALSE
-#endif
-
-#ifndef YY_NULL
-#define YY_NULL 0
-#endif
-
-#ifndef MIN
-#define MIN(a,b) (((a)<(b))?(a):(b))
-#endif
-
-#ifndef BOOL
-#define BOOL unsigned int
-#endif
-
-#ifndef NULL
-#define NULL (void *)0
-#endif
-
-#ifndef NUL
-#define NUL '\0'
-#endif
-
-#ifndef YYDEBUG
-#define YYDEBUG 0
-#endif
-
-typedef enum {
- op_NOP, op_ListElement, op_OidListElement,
- op_True, op_False, op_Not, op_Or, op_And, op_Comp,
- op_EQ, op_NE, op_LT, op_LE, op_GT, op_GE, op_IN, op_REG, op_NRE,
- op_Digit, op_String, op_Regex, op_Var, op_Func
-} ssl_expr_node_op;
-
-typedef struct {
- ssl_expr_node_op node_op;
- void *node_arg1;
- void *node_arg2;
- apr_pool_t *p;
-} ssl_expr_node;
-
-typedef ssl_expr_node ssl_expr;
-
-typedef struct {
- apr_pool_t *pool;
- char *inputbuf;
- int inputlen;
- char *inputptr;
- ssl_expr *expr;
-} ssl_expr_info_type;
-
-extern ssl_expr_info_type ssl_expr_info;
-extern char *ssl_expr_error;
-
-#define yylval ssl_expr_yylval
-#define yyerror ssl_expr_yyerror
-#define yyinput ssl_expr_yyinput
-
-extern int ssl_expr_yyparse(void);
-extern int ssl_expr_yyerror(char *);
-extern int ssl_expr_yylex(void);
-
-extern ssl_expr *ssl_expr_comp(apr_pool_t *, char *);
-extern int ssl_expr_exec(request_rec *, ssl_expr *);
-extern char *ssl_expr_get_error(void);
-extern ssl_expr *ssl_expr_make(ssl_expr_node_op, void *, void *);
-extern BOOL ssl_expr_eval(request_rec *, ssl_expr *);
-
-#endif /* __SSL_EXPR_H__ */
-/** @} */
-
diff --git a/modules/ssl/ssl_expr_eval.c b/modules/ssl/ssl_expr_eval.c
deleted file mode 100644
index f9d6f5ec..00000000
--- a/modules/ssl/ssl_expr_eval.c
+++ /dev/null
@@ -1,345 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* _ _
- * _ __ ___ ___ __| | ___ ___| | mod_ssl
- * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL
- * | | | | | | (_) | (_| | \__ \__ \ |
- * |_| |_| |_|\___/ \__,_|___|___/___/_|
- * |_____|
- * ssl_expr_eval.c
- * Expression Evaluation
- */
- /* ``Make love,
- not software!''
- -- Unknown */
-#include "ssl_private.h"
-
-/* _________________________________________________________________
-**
-** Expression Evaluation
-** _________________________________________________________________
-*/
-
-static BOOL ssl_expr_eval_comp(request_rec *, ssl_expr *);
-static char *ssl_expr_eval_word(request_rec *, ssl_expr *);
-static BOOL ssl_expr_eval_oid(request_rec *r, const char *word, const char *oidstr);
-static char *ssl_expr_eval_func_file(request_rec *, char *);
-static int ssl_expr_eval_strcmplex(char *, char *);
-
-BOOL ssl_expr_eval(request_rec *r, ssl_expr *node)
-{
- switch (node->node_op) {
- case op_True: {
- return TRUE;
- }
- case op_False: {
- return FALSE;
- }
- case op_Not: {
- ssl_expr *e = (ssl_expr *)node->node_arg1;
- return (!ssl_expr_eval(r, e));
- }
- case op_Or: {
- ssl_expr *e1 = (ssl_expr *)node->node_arg1;
- ssl_expr *e2 = (ssl_expr *)node->node_arg2;
- return (ssl_expr_eval(r, e1) || ssl_expr_eval(r, e2));
- }
- case op_And: {
- ssl_expr *e1 = (ssl_expr *)node->node_arg1;
- ssl_expr *e2 = (ssl_expr *)node->node_arg2;
- return (ssl_expr_eval(r, e1) && ssl_expr_eval(r, e2));
- }
- case op_Comp: {
- ssl_expr *e = (ssl_expr *)node->node_arg1;
- return ssl_expr_eval_comp(r, e);
- }
- default: {
- ssl_expr_error = "Internal evaluation error: Unknown expression node";
- return FALSE;
- }
- }
-}
-
-static BOOL ssl_expr_eval_comp(request_rec *r, ssl_expr *node)
-{
- switch (node->node_op) {
- case op_EQ: {
- ssl_expr *e1 = (ssl_expr *)node->node_arg1;
- ssl_expr *e2 = (ssl_expr *)node->node_arg2;
- return (strcmp(ssl_expr_eval_word(r, e1), ssl_expr_eval_word(r, e2)) == 0);
- }
- case op_NE: {
- ssl_expr *e1 = (ssl_expr *)node->node_arg1;
- ssl_expr *e2 = (ssl_expr *)node->node_arg2;
- return (strcmp(ssl_expr_eval_word(r, e1), ssl_expr_eval_word(r, e2)) != 0);
- }
- case op_LT: {
- ssl_expr *e1 = (ssl_expr *)node->node_arg1;
- ssl_expr *e2 = (ssl_expr *)node->node_arg2;
- return (ssl_expr_eval_strcmplex(ssl_expr_eval_word(r, e1), ssl_expr_eval_word(r, e2)) < 0);
- }
- case op_LE: {
- ssl_expr *e1 = (ssl_expr *)node->node_arg1;
- ssl_expr *e2 = (ssl_expr *)node->node_arg2;
- return (ssl_expr_eval_strcmplex(ssl_expr_eval_word(r, e1), ssl_expr_eval_word(r, e2)) <= 0);
- }
- case op_GT: {
- ssl_expr *e1 = (ssl_expr *)node->node_arg1;
- ssl_expr *e2 = (ssl_expr *)node->node_arg2;
- return (ssl_expr_eval_strcmplex(ssl_expr_eval_word(r, e1), ssl_expr_eval_word(r, e2)) > 0);
- }
- case op_GE: {
- ssl_expr *e1 = (ssl_expr *)node->node_arg1;
- ssl_expr *e2 = (ssl_expr *)node->node_arg2;
- return (ssl_expr_eval_strcmplex(ssl_expr_eval_word(r, e1), ssl_expr_eval_word(r, e2)) >= 0);
- }
- case op_IN: {
- ssl_expr *e1 = (ssl_expr *)node->node_arg1;
- ssl_expr *e2 = (ssl_expr *)node->node_arg2;
- ssl_expr *e3;
- char *w1 = ssl_expr_eval_word(r, e1);
- BOOL found = FALSE;
- do {
- ssl_expr_node_op op = e2->node_op;
- e3 = (ssl_expr *)e2->node_arg1;
- e2 = (ssl_expr *)e2->node_arg2;
-
- if (op == op_OidListElement) {
- char *w3 = ssl_expr_eval_word(r, e3);
-
- found = ssl_expr_eval_oid(r, w1, w3);
-
- /* There will be no more nodes on the list, so the result is authoritative */
- break;
- }
-
- if (strcmp(w1, ssl_expr_eval_word(r, e3)) == 0) {
- found = TRUE;
- break;
- }
- } while (e2 != NULL);
- return found;
- }
- case op_REG: {
- ssl_expr *e1;
- ssl_expr *e2;
- char *word;
- ap_regex_t *regex;
-
- e1 = (ssl_expr *)node->node_arg1;
- e2 = (ssl_expr *)node->node_arg2;
- word = ssl_expr_eval_word(r, e1);
- regex = (ap_regex_t *)(e2->node_arg1);
- return (ap_regexec(regex, word, 0, NULL, 0) == 0);
- }
- case op_NRE: {
- ssl_expr *e1;
- ssl_expr *e2;
- char *word;
- ap_regex_t *regex;
-
- e1 = (ssl_expr *)node->node_arg1;
- e2 = (ssl_expr *)node->node_arg2;
- word = ssl_expr_eval_word(r, e1);
- regex = (ap_regex_t *)(e2->node_arg1);
- return !(ap_regexec(regex, word, 0, NULL, 0) == 0);
- }
- default: {
- ssl_expr_error = "Internal evaluation error: Unknown expression node";
- return FALSE;
- }
- }
-}
-
-static char *ssl_expr_eval_word(request_rec *r, ssl_expr *node)
-{
- switch (node->node_op) {
- case op_Digit: {
- char *string = (char *)node->node_arg1;
- return string;
- }
- case op_String: {
- char *string = (char *)node->node_arg1;
- return string;
- }
- case op_Var: {
- char *var = (char *)node->node_arg1;
- char *val = ssl_var_lookup(r->pool, r->server, r->connection, r, var);
- return (val == NULL ? "" : val);
- }
- case op_Func: {
- char *name = (char *)node->node_arg1;
- ssl_expr *args = (ssl_expr *)node->node_arg2;
- if (strEQ(name, "file"))
- return ssl_expr_eval_func_file(r, (char *)(args->node_arg1));
- else {
- ssl_expr_error = "Internal evaluation error: Unknown function name";
- return "";
- }
- }
- default: {
- ssl_expr_error = "Internal evaluation error: Unknown expression node";
- return FALSE;
- }
- }
-}
-
-#define NUM_OID_ELTS 8 /* start with 8 oid slots, resize when needed */
-
-apr_array_header_t *ssl_extlist_by_oid(request_rec *r, const char *oidstr)
-{
- int count = 0, j;
- X509 *xs = NULL;
- ASN1_OBJECT *oid;
- apr_array_header_t *val_array;
- SSLConnRec *sslconn = myConnConfig(r->connection);
-
- /* trivia */
- if (oidstr == NULL || sslconn == NULL || sslconn->ssl == NULL)
- return NULL;
-
- /* Determine the oid we are looking for */
- if ((oid = OBJ_txt2obj(oidstr, 1)) == NULL) {
- ERR_clear_error();
- return NULL;
- }
-
- /* are there any extensions in the cert? */
- if ((xs = SSL_get_peer_certificate(sslconn->ssl)) == NULL ||
- (count = X509_get_ext_count(xs)) == 0) {
- return NULL;
- }
-
- val_array = apr_array_make(r->pool, NUM_OID_ELTS, sizeof(char *));
-
- /* Loop over all extensions, extract the desired oids */
- for (j = 0; j < count; j++) {
- X509_EXTENSION *ext = X509_get_ext(xs, j);
-
- if (OBJ_cmp(ext->object, oid) == 0) {
- BIO *bio = BIO_new(BIO_s_mem());
-
- if (X509V3_EXT_print(bio, ext, 0, 0) == 1) {
- BUF_MEM *buf;
- char **new = apr_array_push(val_array);
-
- BIO_get_mem_ptr(bio, &buf);
-
- *new = apr_pstrmemdup(r->pool, buf->data, buf->length);
- }
-
- BIO_vfree(bio);
- }
- }
-
- X509_free(xs);
- ERR_clear_error();
-
- if (val_array->nelts == 0)
- return NULL;
- else
- return val_array;
-}
-
-static BOOL ssl_expr_eval_oid(request_rec *r, const char *word, const char *oidstr)
-{
- int j;
- BOOL result = FALSE;
- apr_array_header_t *oid_array;
- char **oid_value;
-
- if (NULL == (oid_array = ssl_extlist_by_oid(r, oidstr))) {
- return FALSE;
- }
-
- oid_value = (char **) oid_array->elts;
- for (j = 0; j < oid_array->nelts; j++) {
- if (strcmp(word, oid_value[j]) == 0) {
- result = TRUE;
- break;
- }
- }
- return result;
-}
-
-
-static char *ssl_expr_eval_func_file(request_rec *r, char *filename)
-{
- apr_file_t *fp;
- char *buf;
- apr_off_t offset;
- apr_size_t len;
- apr_finfo_t finfo;
-
- if (apr_file_open(&fp, filename, APR_READ|APR_BUFFERED,
- APR_OS_DEFAULT, r->pool) != APR_SUCCESS) {
- ssl_expr_error = "Cannot open file";
- return "";
- }
- apr_file_info_get(&finfo, APR_FINFO_SIZE, fp);
- if ((finfo.size + 1) != ((apr_size_t)finfo.size + 1)) {
- ssl_expr_error = "Huge file cannot be read";
- apr_file_close(fp);
- return "";
- }
- len = (apr_size_t)finfo.size;
- if (len == 0) {
- buf = (char *)apr_palloc(r->pool, sizeof(char) * 1);
- *buf = NUL;
- }
- else {
- if ((buf = (char *)apr_palloc(r->pool, sizeof(char)*(len+1))) == NULL) {
- ssl_expr_error = "Cannot allocate memory";
- apr_file_close(fp);
- return "";
- }
- offset = 0;
- apr_file_seek(fp, APR_SET, &offset);
- if (apr_file_read(fp, buf, &len) != APR_SUCCESS) {
- ssl_expr_error = "Cannot read from file";
- apr_file_close(fp);
- return "";
- }
- buf[len] = NUL;
- }
- apr_file_close(fp);
- return buf;
-}
-
-/* a variant of strcmp(3) which works correctly also for number strings */
-static int ssl_expr_eval_strcmplex(char *cpNum1, char *cpNum2)
-{
- int i, n1, n2;
-
- if (cpNum1 == NULL)
- return -1;
- if (cpNum2 == NULL)
- return +1;
- n1 = strlen(cpNum1);
- n2 = strlen(cpNum2);
- if (n1 > n2)
- return 1;
- if (n1 < n2)
- return -1;
- for (i = 0; i < n1; i++) {
- if (cpNum1[i] > cpNum2[i])
- return 1;
- if (cpNum1[i] < cpNum2[i])
- return -1;
- }
- return 0;
-}
diff --git a/modules/ssl/ssl_expr_parse.c b/modules/ssl/ssl_expr_parse.c
deleted file mode 100644
index 90475937..00000000
--- a/modules/ssl/ssl_expr_parse.c
+++ /dev/null
@@ -1,618 +0,0 @@
-#ifndef lint
-static char const
-ssl_expr_yyrcsid[] = "$FreeBSD: src/usr.bin/yacc/skeleton.c,v 1.28.2.1 2001/07/19 05:46:39 peter Exp $";
-#endif
-#include <stdlib.h>
-#define YYBYACC 1
-#define YYMAJOR 1
-#define YYMINOR 9
-#define YYLEX ssl_expr_yylex()
-#define YYEMPTY -1
-#define ssl_expr_yyclearin (ssl_expr_yychar=(YYEMPTY))
-#define ssl_expr_yyerrok (ssl_expr_yyerrflag=0)
-#define YYRECOVERING() (ssl_expr_yyerrflag!=0)
-#if defined(__cplusplus) || __STDC__
-static int ssl_expr_yygrowstack(void);
-#else
-static int ssl_expr_yygrowstack();
-#endif
-#define YYPREFIX "ssl_expr_yy"
-#line 36 "ssl_expr_parse.y"
-#include "ssl_private.h"
-#line 39 "ssl_expr_parse.y"
-typedef union {
- char *cpVal;
- ssl_expr *exVal;
-} YYSTYPE;
-#line 28 "y.tab.c"
-#define YYERRCODE 256
-#define T_TRUE 257
-#define T_FALSE 258
-#define T_DIGIT 259
-#define T_ID 260
-#define T_STRING 261
-#define T_REGEX 262
-#define T_REGEX_I 263
-#define T_FUNC_FILE 264
-#define T_OP_EQ 265
-#define T_OP_NE 266
-#define T_OP_LT 267
-#define T_OP_LE 268
-#define T_OP_GT 269
-#define T_OP_GE 270
-#define T_OP_REG 271
-#define T_OP_NRE 272
-#define T_OP_IN 273
-#define T_OP_OID 274
-#define T_OP_OR 275
-#define T_OP_AND 276
-#define T_OP_NOT 277
-const short ssl_expr_yylhs[] = { -1,
- 0, 1, 1, 1, 1, 1, 1, 1, 2, 2,
- 2, 2, 2, 2, 2, 2, 2, 6, 6, 5,
- 5, 7, 7, 7, 7, 4, 4, 3,
-};
-const short ssl_expr_yylen[] = { 2,
- 1, 1, 1, 2, 3, 3, 1, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 4, 3, 1,
- 3, 1, 1, 4, 1, 1, 1, 4,
-};
-const short ssl_expr_yydefred[] = { 0,
- 2, 3, 22, 23, 0, 0, 0, 0, 0, 0,
- 7, 25, 0, 0, 4, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 8,
- 0, 0, 6, 9, 10, 11, 12, 13, 14, 26,
- 27, 16, 17, 0, 0, 15, 28, 24, 0, 0,
- 20, 0, 19, 0, 18, 21,
-};
-const short ssl_expr_yydgoto[] = { 9,
- 10, 11, 12, 42, 50, 46, 13,
-};
-const short ssl_expr_yysindex[] = { -37,
- 0, 0, 0, 0, -16, -37, -37, -92, 0, -248,
- 0, 0, -250, -228, 0, -39, -226, -37, -37, -33,
- -33, -33, -33, -33, -33, -233, -233, -118, -6, 0,
- -88, -238, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, -1, -33, 0, 0, 0, -33, -38,
- 0, 2, 0, -33, 0, 0,
-};
-const short ssl_expr_yyrindex[] = { 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 40,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0,
-};
-const short ssl_expr_yygindex[] = { 0,
- 7, 0, 0, 17, 0, 0, -13,
-};
-#define YYTABLESIZE 276
-const short ssl_expr_yytable[] = { 8,
- 5, 30, 7, 8, 45, 54, 34, 35, 36, 37,
- 38, 39, 15, 16, 20, 21, 22, 23, 24, 25,
- 26, 27, 28, 14, 32, 33, 18, 19, 40, 41,
- 17, 51, 29, 31, 47, 52, 48, 19, 49, 1,
- 56, 5, 55, 43, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 53, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 44, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
- 2, 3, 0, 4, 0, 3, 5, 4, 0, 0,
- 5, 0, 0, 0, 0, 18, 19, 0, 0, 6,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 5,
-};
-const short ssl_expr_yycheck[] = { 37,
- 0, 41, 40, 37, 123, 44, 20, 21, 22, 23,
- 24, 25, 6, 7, 265, 266, 267, 268, 269, 270,
- 271, 272, 273, 40, 18, 19, 275, 276, 262, 263,
- 123, 45, 261, 260, 41, 49, 125, 276, 40, 0,
- 54, 41, 41, 27, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, 125, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 274, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, 257,
- 258, 259, -1, 261, -1, 259, 264, 261, -1, -1,
- 264, -1, -1, -1, -1, 275, 276, -1, -1, 277,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, 275,
-};
-#define YYFINAL 9
-#ifndef YYDEBUG
-#define YYDEBUG 0
-#endif
-#define YYMAXTOKEN 277
-#if YYDEBUG
-const char * const ssl_expr_yyname[] = {
-"end-of-file",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,"'%'",0,0,"'('","')'",0,0,"','",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"'{'",0,"'}'",0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,"T_TRUE",
-"T_FALSE","T_DIGIT","T_ID","T_STRING","T_REGEX","T_REGEX_I","T_FUNC_FILE",
-"T_OP_EQ","T_OP_NE","T_OP_LT","T_OP_LE","T_OP_GT","T_OP_GE","T_OP_REG",
-"T_OP_NRE","T_OP_IN","T_OP_OID","T_OP_OR","T_OP_AND","T_OP_NOT",
-};
-const char * const ssl_expr_yyrule[] = {
-"$accept : root",
-"root : expr",
-"expr : T_TRUE",
-"expr : T_FALSE",
-"expr : T_OP_NOT expr",
-"expr : expr T_OP_OR expr",
-"expr : expr T_OP_AND expr",
-"expr : comparison",
-"expr : '(' expr ')'",
-"comparison : word T_OP_EQ word",
-"comparison : word T_OP_NE word",
-"comparison : word T_OP_LT word",
-"comparison : word T_OP_LE word",
-"comparison : word T_OP_GT word",
-"comparison : word T_OP_GE word",
-"comparison : word T_OP_IN wordlist",
-"comparison : word T_OP_REG regex",
-"comparison : word T_OP_NRE regex",
-"wordlist : T_OP_OID '(' word ')'",
-"wordlist : '{' words '}'",
-"words : word",
-"words : words ',' word",
-"word : T_DIGIT",
-"word : T_STRING",
-"word : '%' '{' T_ID '}'",
-"word : funccall",
-"regex : T_REGEX",
-"regex : T_REGEX_I",
-"funccall : T_FUNC_FILE '(' T_STRING ')'",
-};
-#endif
-#if YYDEBUG
-#include <stdio.h>
-#endif
-#ifdef YYSTACKSIZE
-#undef YYMAXDEPTH
-#define YYMAXDEPTH YYSTACKSIZE
-#else
-#ifdef YYMAXDEPTH
-#define YYSTACKSIZE YYMAXDEPTH
-#else
-#define YYSTACKSIZE 10000
-#define YYMAXDEPTH 10000
-#endif
-#endif
-#define YYINITSTACKSIZE 200
-int ssl_expr_yydebug;
-int ssl_expr_yynerrs;
-int ssl_expr_yyerrflag;
-int ssl_expr_yychar;
-short *ssl_expr_yyssp;
-YYSTYPE *ssl_expr_yyvsp;
-YYSTYPE ssl_expr_yyval;
-YYSTYPE ssl_expr_yylval;
-short *ssl_expr_yyss;
-short *ssl_expr_yysslim;
-YYSTYPE *ssl_expr_yyvs;
-int ssl_expr_yystacksize;
-#line 148 "ssl_expr_parse.y"
-
-int ssl_expr_yyerror(char *s)
-{
- ssl_expr_error = s;
- return 2;
-}
-
-#line 237 "y.tab.c"
-/* allocate initial stack or double stack size, up to YYMAXDEPTH */
-static int ssl_expr_yygrowstack()
-{
- int newsize, i;
- short *newss;
- YYSTYPE *newvs;
-
- if ((newsize = ssl_expr_yystacksize) == 0)
- newsize = YYINITSTACKSIZE;
- else if (newsize >= YYMAXDEPTH)
- return -1;
- else if ((newsize *= 2) > YYMAXDEPTH)
- newsize = YYMAXDEPTH;
- i = ssl_expr_yyssp - ssl_expr_yyss;
- newss = ssl_expr_yyss ? (short *)realloc(ssl_expr_yyss, newsize * sizeof *newss) :
- (short *)malloc(newsize * sizeof *newss);
- if (newss == NULL)
- return -1;
- ssl_expr_yyss = newss;
- ssl_expr_yyssp = newss + i;
- newvs = ssl_expr_yyvs ? (YYSTYPE *)realloc(ssl_expr_yyvs, newsize * sizeof *newvs) :
- (YYSTYPE *)malloc(newsize * sizeof *newvs);
- if (newvs == NULL)
- return -1;
- ssl_expr_yyvs = newvs;
- ssl_expr_yyvsp = newvs + i;
- ssl_expr_yystacksize = newsize;
- ssl_expr_yysslim = ssl_expr_yyss + newsize - 1;
- return 0;
-}
-
-#define YYABORT goto ssl_expr_yyabort
-#define YYREJECT goto ssl_expr_yyabort
-#define YYACCEPT goto ssl_expr_yyaccept
-#define YYERROR goto ssl_expr_yyerrlab
-
-#ifndef YYPARSE_PARAM
-#if defined(__cplusplus) || __STDC__
-#define YYPARSE_PARAM_ARG void
-#define YYPARSE_PARAM_DECL
-#else /* ! ANSI-C/C++ */
-#define YYPARSE_PARAM_ARG
-#define YYPARSE_PARAM_DECL
-#endif /* ANSI-C/C++ */
-#else /* YYPARSE_PARAM */
-#ifndef YYPARSE_PARAM_TYPE
-#define YYPARSE_PARAM_TYPE void *
-#endif
-#if defined(__cplusplus) || __STDC__
-#define YYPARSE_PARAM_ARG YYPARSE_PARAM_TYPE YYPARSE_PARAM
-#define YYPARSE_PARAM_DECL
-#else /* ! ANSI-C/C++ */
-#define YYPARSE_PARAM_ARG YYPARSE_PARAM
-#define YYPARSE_PARAM_DECL YYPARSE_PARAM_TYPE YYPARSE_PARAM;
-#endif /* ANSI-C/C++ */
-#endif /* ! YYPARSE_PARAM */
-
-int
-ssl_expr_yyparse (YYPARSE_PARAM_ARG)
- YYPARSE_PARAM_DECL
-{
- register int ssl_expr_yym, ssl_expr_yyn, ssl_expr_yystate;
-#if YYDEBUG
- register const char *ssl_expr_yys;
-
- if ((ssl_expr_yys = getenv("YYDEBUG")))
- {
- ssl_expr_yyn = *ssl_expr_yys;
- if (ssl_expr_yyn >= '0' && ssl_expr_yyn <= '9')
- ssl_expr_yydebug = ssl_expr_yyn - '0';
- }
-#endif
-
- ssl_expr_yynerrs = 0;
- ssl_expr_yyerrflag = 0;
- ssl_expr_yychar = (-1);
-
- if (ssl_expr_yyss == NULL && ssl_expr_yygrowstack()) goto ssl_expr_yyoverflow;
- ssl_expr_yyssp = ssl_expr_yyss;
- ssl_expr_yyvsp = ssl_expr_yyvs;
- *ssl_expr_yyssp = ssl_expr_yystate = 0;
-
-ssl_expr_yyloop:
- if ((ssl_expr_yyn = ssl_expr_yydefred[ssl_expr_yystate])) goto ssl_expr_yyreduce;
- if (ssl_expr_yychar < 0)
- {
- if ((ssl_expr_yychar = ssl_expr_yylex()) < 0) ssl_expr_yychar = 0;
-#if YYDEBUG
- if (ssl_expr_yydebug)
- {
- ssl_expr_yys = 0;
- if (ssl_expr_yychar <= YYMAXTOKEN) ssl_expr_yys = ssl_expr_yyname[ssl_expr_yychar];
- if (!ssl_expr_yys) ssl_expr_yys = "illegal-symbol";
- printf("%sdebug: state %d, reading %d (%s)\n",
- YYPREFIX, ssl_expr_yystate, ssl_expr_yychar, ssl_expr_yys);
- }
-#endif
- }
- if ((ssl_expr_yyn = ssl_expr_yysindex[ssl_expr_yystate]) && (ssl_expr_yyn += ssl_expr_yychar) >= 0 &&
- ssl_expr_yyn <= YYTABLESIZE && ssl_expr_yycheck[ssl_expr_yyn] == ssl_expr_yychar)
- {
-#if YYDEBUG
- if (ssl_expr_yydebug)
- printf("%sdebug: state %d, shifting to state %d\n",
- YYPREFIX, ssl_expr_yystate, ssl_expr_yytable[ssl_expr_yyn]);
-#endif
- if (ssl_expr_yyssp >= ssl_expr_yysslim && ssl_expr_yygrowstack())
- {
- goto ssl_expr_yyoverflow;
- }
- *++ssl_expr_yyssp = ssl_expr_yystate = ssl_expr_yytable[ssl_expr_yyn];
- *++ssl_expr_yyvsp = ssl_expr_yylval;
- ssl_expr_yychar = (-1);
- if (ssl_expr_yyerrflag > 0) --ssl_expr_yyerrflag;
- goto ssl_expr_yyloop;
- }
- if ((ssl_expr_yyn = ssl_expr_yyrindex[ssl_expr_yystate]) && (ssl_expr_yyn += ssl_expr_yychar) >= 0 &&
- ssl_expr_yyn <= YYTABLESIZE && ssl_expr_yycheck[ssl_expr_yyn] == ssl_expr_yychar)
- {
- ssl_expr_yyn = ssl_expr_yytable[ssl_expr_yyn];
- goto ssl_expr_yyreduce;
- }
- if (ssl_expr_yyerrflag) goto ssl_expr_yyinrecovery;
-#if defined(lint) || defined(__GNUC__)
- goto ssl_expr_yynewerror;
-#endif
-ssl_expr_yynewerror:
- ssl_expr_yyerror("syntax error");
-#if defined(lint) || defined(__GNUC__)
- goto ssl_expr_yyerrlab;
-#endif
-ssl_expr_yyerrlab:
- ++ssl_expr_yynerrs;
-ssl_expr_yyinrecovery:
- if (ssl_expr_yyerrflag < 3)
- {
- ssl_expr_yyerrflag = 3;
- for (;;)
- {
- if ((ssl_expr_yyn = ssl_expr_yysindex[*ssl_expr_yyssp]) && (ssl_expr_yyn += YYERRCODE) >= 0 &&
- ssl_expr_yyn <= YYTABLESIZE && ssl_expr_yycheck[ssl_expr_yyn] == YYERRCODE)
- {
-#if YYDEBUG
- if (ssl_expr_yydebug)
- printf("%sdebug: state %d, error recovery shifting\
- to state %d\n", YYPREFIX, *ssl_expr_yyssp, ssl_expr_yytable[ssl_expr_yyn]);
-#endif
- if (ssl_expr_yyssp >= ssl_expr_yysslim && ssl_expr_yygrowstack())
- {
- goto ssl_expr_yyoverflow;
- }
- *++ssl_expr_yyssp = ssl_expr_yystate = ssl_expr_yytable[ssl_expr_yyn];
- *++ssl_expr_yyvsp = ssl_expr_yylval;
- goto ssl_expr_yyloop;
- }
- else
- {
-#if YYDEBUG
- if (ssl_expr_yydebug)
- printf("%sdebug: error recovery discarding state %d\n",
- YYPREFIX, *ssl_expr_yyssp);
-#endif
- if (ssl_expr_yyssp <= ssl_expr_yyss) goto ssl_expr_yyabort;
- --ssl_expr_yyssp;
- --ssl_expr_yyvsp;
- }
- }
- }
- else
- {
- if (ssl_expr_yychar == 0) goto ssl_expr_yyabort;
-#if YYDEBUG
- if (ssl_expr_yydebug)
- {
- ssl_expr_yys = 0;
- if (ssl_expr_yychar <= YYMAXTOKEN) ssl_expr_yys = ssl_expr_yyname[ssl_expr_yychar];
- if (!ssl_expr_yys) ssl_expr_yys = "illegal-symbol";
- printf("%sdebug: state %d, error recovery discards token %d (%s)\n",
- YYPREFIX, ssl_expr_yystate, ssl_expr_yychar, ssl_expr_yys);
- }
-#endif
- ssl_expr_yychar = (-1);
- goto ssl_expr_yyloop;
- }
-ssl_expr_yyreduce:
-#if YYDEBUG
- if (ssl_expr_yydebug)
- printf("%sdebug: state %d, reducing by rule %d (%s)\n",
- YYPREFIX, ssl_expr_yystate, ssl_expr_yyn, ssl_expr_yyrule[ssl_expr_yyn]);
-#endif
- ssl_expr_yym = ssl_expr_yylen[ssl_expr_yyn];
- ssl_expr_yyval = ssl_expr_yyvsp[1-ssl_expr_yym];
- switch (ssl_expr_yyn)
- {
-case 1:
-#line 84 "ssl_expr_parse.y"
-{ ssl_expr_info.expr = ssl_expr_yyvsp[0].exVal; }
-break;
-case 2:
-#line 87 "ssl_expr_parse.y"
-{ ssl_expr_yyval.exVal = ssl_expr_make(op_True, NULL, NULL); }
-break;
-case 3:
-#line 88 "ssl_expr_parse.y"
-{ ssl_expr_yyval.exVal = ssl_expr_make(op_False, NULL, NULL); }
-break;
-case 4:
-#line 89 "ssl_expr_parse.y"
-{ ssl_expr_yyval.exVal = ssl_expr_make(op_Not, ssl_expr_yyvsp[0].exVal, NULL); }
-break;
-case 5:
-#line 90 "ssl_expr_parse.y"
-{ ssl_expr_yyval.exVal = ssl_expr_make(op_Or, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); }
-break;
-case 6:
-#line 91 "ssl_expr_parse.y"
-{ ssl_expr_yyval.exVal = ssl_expr_make(op_And, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); }
-break;
-case 7:
-#line 92 "ssl_expr_parse.y"
-{ ssl_expr_yyval.exVal = ssl_expr_make(op_Comp, ssl_expr_yyvsp[0].exVal, NULL); }
-break;
-case 8:
-#line 93 "ssl_expr_parse.y"
-{ ssl_expr_yyval.exVal = ssl_expr_yyvsp[-1].exVal; }
-break;
-case 9:
-#line 96 "ssl_expr_parse.y"
-{ ssl_expr_yyval.exVal = ssl_expr_make(op_EQ, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); }
-break;
-case 10:
-#line 97 "ssl_expr_parse.y"
-{ ssl_expr_yyval.exVal = ssl_expr_make(op_NE, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); }
-break;
-case 11:
-#line 98 "ssl_expr_parse.y"
-{ ssl_expr_yyval.exVal = ssl_expr_make(op_LT, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); }
-break;
-case 12:
-#line 99 "ssl_expr_parse.y"
-{ ssl_expr_yyval.exVal = ssl_expr_make(op_LE, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); }
-break;
-case 13:
-#line 100 "ssl_expr_parse.y"
-{ ssl_expr_yyval.exVal = ssl_expr_make(op_GT, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); }
-break;
-case 14:
-#line 101 "ssl_expr_parse.y"
-{ ssl_expr_yyval.exVal = ssl_expr_make(op_GE, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); }
-break;
-case 15:
-#line 102 "ssl_expr_parse.y"
-{ ssl_expr_yyval.exVal = ssl_expr_make(op_IN, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); }
-break;
-case 16:
-#line 103 "ssl_expr_parse.y"
-{ ssl_expr_yyval.exVal = ssl_expr_make(op_REG, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); }
-break;
-case 17:
-#line 104 "ssl_expr_parse.y"
-{ ssl_expr_yyval.exVal = ssl_expr_make(op_NRE, ssl_expr_yyvsp[-2].exVal, ssl_expr_yyvsp[0].exVal); }
-break;
-case 18:
-#line 107 "ssl_expr_parse.y"
-{ ssl_expr_yyval.exVal = ssl_expr_make(op_OidListElement, ssl_expr_yyvsp[-1].exVal, NULL); }
-break;
-case 19:
-#line 108 "ssl_expr_parse.y"
-{ ssl_expr_yyval.exVal = ssl_expr_yyvsp[-1].exVal ; }
-break;
-case 20:
-#line 111 "ssl_expr_parse.y"
-{ ssl_expr_yyval.exVal = ssl_expr_make(op_ListElement, ssl_expr_yyvsp[0].exVal, NULL); }
-break;
-case 21:
-#line 112 "ssl_expr_parse.y"
-{ ssl_expr_yyval.exVal = ssl_expr_make(op_ListElement, ssl_expr_yyvsp[0].exVal, ssl_expr_yyvsp[-2].exVal); }
-break;
-case 22:
-#line 115 "ssl_expr_parse.y"
-{ ssl_expr_yyval.exVal = ssl_expr_make(op_Digit, ssl_expr_yyvsp[0].cpVal, NULL); }
-break;
-case 23:
-#line 116 "ssl_expr_parse.y"
-{ ssl_expr_yyval.exVal = ssl_expr_make(op_String, ssl_expr_yyvsp[0].cpVal, NULL); }
-break;
-case 24:
-#line 117 "ssl_expr_parse.y"
-{ ssl_expr_yyval.exVal = ssl_expr_make(op_Var, ssl_expr_yyvsp[-1].cpVal, NULL); }
-break;
-case 25:
-#line 118 "ssl_expr_parse.y"
-{ ssl_expr_yyval.exVal = ssl_expr_yyvsp[0].exVal; }
-break;
-case 26:
-#line 121 "ssl_expr_parse.y"
-{
- ap_regex_t *regex;
- if ((regex = ap_pregcomp(ssl_expr_info.pool, ssl_expr_yyvsp[0].cpVal,
- AP_REG_EXTENDED|AP_REG_NOSUB)) == NULL) {
- ssl_expr_error = "Failed to compile regular expression";
- YYERROR;
- }
- ssl_expr_yyval.exVal = ssl_expr_make(op_Regex, regex, NULL);
- }
-break;
-case 27:
-#line 130 "ssl_expr_parse.y"
-{
- ap_regex_t *regex;
- if ((regex = ap_pregcomp(ssl_expr_info.pool, ssl_expr_yyvsp[0].cpVal,
- AP_REG_EXTENDED|AP_REG_NOSUB|AP_REG_ICASE)) == NULL) {
- ssl_expr_error = "Failed to compile regular expression";
- YYERROR;
- }
- ssl_expr_yyval.exVal = ssl_expr_make(op_Regex, regex, NULL);
- }
-break;
-case 28:
-#line 141 "ssl_expr_parse.y"
-{
- ssl_expr *args = ssl_expr_make(op_ListElement, ssl_expr_yyvsp[-1].cpVal, NULL);
- ssl_expr_yyval.exVal = ssl_expr_make(op_Func, "file", args);
- }
-break;
-#line 563 "y.tab.c"
- }
- ssl_expr_yyssp -= ssl_expr_yym;
- ssl_expr_yystate = *ssl_expr_yyssp;
- ssl_expr_yyvsp -= ssl_expr_yym;
- ssl_expr_yym = ssl_expr_yylhs[ssl_expr_yyn];
- if (ssl_expr_yystate == 0 && ssl_expr_yym == 0)
- {
-#if YYDEBUG
- if (ssl_expr_yydebug)
- printf("%sdebug: after reduction, shifting from state 0 to\
- state %d\n", YYPREFIX, YYFINAL);
-#endif
- ssl_expr_yystate = YYFINAL;
- *++ssl_expr_yyssp = YYFINAL;
- *++ssl_expr_yyvsp = ssl_expr_yyval;
- if (ssl_expr_yychar < 0)
- {
- if ((ssl_expr_yychar = ssl_expr_yylex()) < 0) ssl_expr_yychar = 0;
-#if YYDEBUG
- if (ssl_expr_yydebug)
- {
- ssl_expr_yys = 0;
- if (ssl_expr_yychar <= YYMAXTOKEN) ssl_expr_yys = ssl_expr_yyname[ssl_expr_yychar];
- if (!ssl_expr_yys) ssl_expr_yys = "illegal-symbol";
- printf("%sdebug: state %d, reading %d (%s)\n",
- YYPREFIX, YYFINAL, ssl_expr_yychar, ssl_expr_yys);
- }
-#endif
- }
- if (ssl_expr_yychar == 0) goto ssl_expr_yyaccept;
- goto ssl_expr_yyloop;
- }
- if ((ssl_expr_yyn = ssl_expr_yygindex[ssl_expr_yym]) && (ssl_expr_yyn += ssl_expr_yystate) >= 0 &&
- ssl_expr_yyn <= YYTABLESIZE && ssl_expr_yycheck[ssl_expr_yyn] == ssl_expr_yystate)
- ssl_expr_yystate = ssl_expr_yytable[ssl_expr_yyn];
- else
- ssl_expr_yystate = ssl_expr_yydgoto[ssl_expr_yym];
-#if YYDEBUG
- if (ssl_expr_yydebug)
- printf("%sdebug: after reduction, shifting from state %d \
-to state %d\n", YYPREFIX, *ssl_expr_yyssp, ssl_expr_yystate);
-#endif
- if (ssl_expr_yyssp >= ssl_expr_yysslim && ssl_expr_yygrowstack())
- {
- goto ssl_expr_yyoverflow;
- }
- *++ssl_expr_yyssp = ssl_expr_yystate;
- *++ssl_expr_yyvsp = ssl_expr_yyval;
- goto ssl_expr_yyloop;
-ssl_expr_yyoverflow:
- ssl_expr_yyerror("yacc stack overflow");
-ssl_expr_yyabort:
- return (1);
-ssl_expr_yyaccept:
- return (0);
-}
diff --git a/modules/ssl/ssl_expr_parse.h b/modules/ssl/ssl_expr_parse.h
deleted file mode 100644
index 66952eb1..00000000
--- a/modules/ssl/ssl_expr_parse.h
+++ /dev/null
@@ -1,30 +0,0 @@
-#ifndef YYERRCODE
-#define YYERRCODE 256
-#endif
-
-#define T_TRUE 257
-#define T_FALSE 258
-#define T_DIGIT 259
-#define T_ID 260
-#define T_STRING 261
-#define T_REGEX 262
-#define T_REGEX_I 263
-#define T_FUNC_FILE 264
-#define T_OP_EQ 265
-#define T_OP_NE 266
-#define T_OP_LT 267
-#define T_OP_LE 268
-#define T_OP_GT 269
-#define T_OP_GE 270
-#define T_OP_REG 271
-#define T_OP_NRE 272
-#define T_OP_IN 273
-#define T_OP_OID 274
-#define T_OP_OR 275
-#define T_OP_AND 276
-#define T_OP_NOT 277
-typedef union {
- char *cpVal;
- ssl_expr *exVal;
-} YYSTYPE;
-extern YYSTYPE ssl_expr_yylval;
diff --git a/modules/ssl/ssl_expr_parse.y b/modules/ssl/ssl_expr_parse.y
deleted file mode 100644
index a30fc8e7..00000000
--- a/modules/ssl/ssl_expr_parse.y
+++ /dev/null
@@ -1,154 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* _ _
- * _ __ ___ ___ __| | ___ ___| |
- * | '_ ` _ \ / _ \ / _` | / __/ __| |
- * | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to OpenSSL
- * |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.modssl.org/
- * |_____|
- * ssl_expr_parse.y
- * Expression LR(1) Parser
- */
- /* ``What you see is all you get.''
- -- Brian Kernighan */
-
-/* _________________________________________________________________
-**
-** Expression Parser
-** _________________________________________________________________
-*/
-
-%{
-#include "ssl_private.h"
-%}
-
-%union {
- char *cpVal;
- ssl_expr *exVal;
-}
-
-%token T_TRUE
-%token T_FALSE
-
-%token <cpVal> T_DIGIT
-%token <cpVal> T_ID
-%token <cpVal> T_STRING
-%token <cpVal> T_REGEX
-%token <cpVal> T_REGEX_I
-
-%token T_FUNC_FILE
-
-%token T_OP_EQ
-%token T_OP_NE
-%token T_OP_LT
-%token T_OP_LE
-%token T_OP_GT
-%token T_OP_GE
-%token T_OP_REG
-%token T_OP_NRE
-%token T_OP_IN
-%token T_OP_OID
-
-%token T_OP_OR
-%token T_OP_AND
-%token T_OP_NOT
-
-%left T_OP_OR
-%left T_OP_AND
-%left T_OP_NOT
-
-%type <exVal> expr
-%type <exVal> comparison
-%type <exVal> funccall
-%type <exVal> regex
-%type <exVal> words
-%type <exVal> wordlist
-%type <exVal> word
-
-%%
-
-root : expr { ssl_expr_info.expr = $1; }
- ;
-
-expr : T_TRUE { $$ = ssl_expr_make(op_True, NULL, NULL); }
- | T_FALSE { $$ = ssl_expr_make(op_False, NULL, NULL); }
- | T_OP_NOT expr { $$ = ssl_expr_make(op_Not, $2, NULL); }
- | expr T_OP_OR expr { $$ = ssl_expr_make(op_Or, $1, $3); }
- | expr T_OP_AND expr { $$ = ssl_expr_make(op_And, $1, $3); }
- | comparison { $$ = ssl_expr_make(op_Comp, $1, NULL); }
- | '(' expr ')' { $$ = $2; }
- ;
-
-comparison: word T_OP_EQ word { $$ = ssl_expr_make(op_EQ, $1, $3); }
- | word T_OP_NE word { $$ = ssl_expr_make(op_NE, $1, $3); }
- | word T_OP_LT word { $$ = ssl_expr_make(op_LT, $1, $3); }
- | word T_OP_LE word { $$ = ssl_expr_make(op_LE, $1, $3); }
- | word T_OP_GT word { $$ = ssl_expr_make(op_GT, $1, $3); }
- | word T_OP_GE word { $$ = ssl_expr_make(op_GE, $1, $3); }
- | word T_OP_IN wordlist { $$ = ssl_expr_make(op_IN, $1, $3); }
- | word T_OP_REG regex { $$ = ssl_expr_make(op_REG, $1, $3); }
- | word T_OP_NRE regex { $$ = ssl_expr_make(op_NRE, $1, $3); }
- ;
-
-wordlist : T_OP_OID '(' word ')' { $$ = ssl_expr_make(op_OidListElement, $3, NULL); }
- | '{' words '}' { $$ = $2 ; }
- ;
-
-words : word { $$ = ssl_expr_make(op_ListElement, $1, NULL); }
- | words ',' word { $$ = ssl_expr_make(op_ListElement, $3, $1); }
- ;
-
-word : T_DIGIT { $$ = ssl_expr_make(op_Digit, $1, NULL); }
- | T_STRING { $$ = ssl_expr_make(op_String, $1, NULL); }
- | '%' '{' T_ID '}' { $$ = ssl_expr_make(op_Var, $3, NULL); }
- | funccall { $$ = $1; }
- ;
-
-regex : T_REGEX {
- ap_regex_t *regex;
- if ((regex = ap_pregcomp(ssl_expr_info.pool, $1,
- AP_REG_EXTENDED|AP_REG_NOSUB)) == NULL) {
- ssl_expr_error = "Failed to compile regular expression";
- YYERROR;
- }
- $$ = ssl_expr_make(op_Regex, regex, NULL);
- }
- | T_REGEX_I {
- ap_regex_t *regex;
- if ((regex = ap_pregcomp(ssl_expr_info.pool, $1,
- AP_REG_EXTENDED|AP_REG_NOSUB|AP_REG_ICASE)) == NULL) {
- ssl_expr_error = "Failed to compile regular expression";
- YYERROR;
- }
- $$ = ssl_expr_make(op_Regex, regex, NULL);
- }
- ;
-
-funccall : T_FUNC_FILE '(' T_STRING ')' {
- ssl_expr *args = ssl_expr_make(op_ListElement, $3, NULL);
- $$ = ssl_expr_make(op_Func, "file", args);
- }
- ;
-
-%%
-
-int yyerror(char *s)
-{
- ssl_expr_error = s;
- return 2;
-}
-
diff --git a/modules/ssl/ssl_expr_scan.c b/modules/ssl/ssl_expr_scan.c
deleted file mode 100644
index 278eba40..00000000
--- a/modules/ssl/ssl_expr_scan.c
+++ /dev/null
@@ -1,1975 +0,0 @@
-#define yy_create_buffer ssl_expr_yy_create_buffer
-#define yy_delete_buffer ssl_expr_yy_delete_buffer
-#define yy_scan_buffer ssl_expr_yy_scan_buffer
-#define yy_scan_string ssl_expr_yy_scan_string
-#define yy_scan_bytes ssl_expr_yy_scan_bytes
-#define yy_flex_debug ssl_expr_yy_flex_debug
-#define yy_init_buffer ssl_expr_yy_init_buffer
-#define yy_flush_buffer ssl_expr_yy_flush_buffer
-#define yy_load_buffer_state ssl_expr_yy_load_buffer_state
-#define yy_switch_to_buffer ssl_expr_yy_switch_to_buffer
-#define yyin ssl_expr_yyin
-#define yyleng ssl_expr_yyleng
-#define yylex ssl_expr_yylex
-#define yyout ssl_expr_yyout
-#define yyrestart ssl_expr_yyrestart
-#define yytext ssl_expr_yytext
-
-/* A lexical scanner generated by flex */
-
-/* Scanner skeleton version:
- * $FreeBSD: src/usr.bin/lex/flex.skl,v 1.4 1999/10/27 07:56:44 obrien Exp $
- */
-
-#define FLEX_SCANNER
-#define YY_FLEX_MAJOR_VERSION 2
-#define YY_FLEX_MINOR_VERSION 5
-
-#include <stdio.h>
-
-
-/* cfront 1.2 defines "c_plusplus" instead of "__cplusplus" */
-#ifdef c_plusplus
-#ifndef __cplusplus
-#define __cplusplus
-#endif
-#endif
-
-
-#ifdef __cplusplus
-
-#include <stdlib.h>
-#include <unistd.h>
-
-/* Use prototypes in function declarations. */
-#define YY_USE_PROTOS
-
-/* The "const" storage-class-modifier is valid. */
-#define YY_USE_CONST
-
-#else /* ! __cplusplus */
-
-#if __STDC__
-
-#define YY_USE_PROTOS
-#define YY_USE_CONST
-
-#endif /* __STDC__ */
-#endif /* ! __cplusplus */
-
-#ifdef __TURBOC__
- #pragma warn -rch
- #pragma warn -use
-#include <io.h>
-#include <stdlib.h>
-#define YY_USE_CONST
-#define YY_USE_PROTOS
-#endif
-
-#ifdef YY_USE_CONST
-#define yyconst const
-#else
-#define yyconst
-#endif
-
-
-#ifdef YY_USE_PROTOS
-#define YY_PROTO(proto) proto
-#else
-#define YY_PROTO(proto) ()
-#endif
-
-/* Returned upon end-of-file. */
-#define YY_NULL 0
-
-/* Promotes a possibly negative, possibly signed char to an unsigned
- * integer for use as an array index. If the signed char is negative,
- * we want to instead treat it as an 8-bit unsigned char, hence the
- * double cast.
- */
-#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
-
-/* Enter a start condition. This macro really ought to take a parameter,
- * but we do it the disgusting crufty way forced on us by the ()-less
- * definition of BEGIN.
- */
-#define BEGIN yy_start = 1 + 2 *
-
-/* Translate the current start state into a value that can be later handed
- * to BEGIN to return to the state. The YYSTATE alias is for lex
- * compatibility.
- */
-#define YY_START ((yy_start - 1) / 2)
-#define YYSTATE YY_START
-
-/* Action number for EOF rule of a given start state. */
-#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
-
-/* Special action meaning "start processing a new file". */
-#define YY_NEW_FILE yyrestart( yyin )
-
-#define YY_END_OF_BUFFER_CHAR 0
-
-/* Size of default input buffer. */
-#define YY_BUF_SIZE 16384
-
-typedef struct yy_buffer_state *YY_BUFFER_STATE;
-
-extern int yyleng;
-extern FILE *yyin, *yyout;
-
-#define EOB_ACT_CONTINUE_SCAN 0
-#define EOB_ACT_END_OF_FILE 1
-#define EOB_ACT_LAST_MATCH 2
-
-/* The funky do-while in the following #define is used to turn the definition
- * int a single C statement (which needs a semi-colon terminator). This
- * avoids problems with code like:
- *
- * if ( condition_holds )
- * yyless( 5 );
- * else
- * do_something_else();
- *
- * Prior to using the do-while the compiler would get upset at the
- * "else" because it interpreted the "if" statement as being all
- * done when it reached the ';' after the yyless() call.
- */
-
-/* Return all but the first 'n' matched characters back to the input stream. */
-
-#define yyless(n) \
- do \
- { \
- /* Undo effects of setting up yytext. */ \
- *yy_cp = yy_hold_char; \
- YY_RESTORE_YY_MORE_OFFSET \
- yy_c_buf_p = yy_cp = yy_bp + n - YY_MORE_ADJ; \
- YY_DO_BEFORE_ACTION; /* set up yytext again */ \
- } \
- while ( 0 )
-
-#define unput(c) yyunput( c, yytext_ptr )
-
-/* The following is because we cannot portably get our hands on size_t
- * (without autoconf's help, which isn't available because we want
- * flex-generated scanners to compile on their own).
- */
-typedef unsigned int yy_size_t;
-
-
-struct yy_buffer_state
- {
- FILE *yy_input_file;
-
- char *yy_ch_buf; /* input buffer */
- char *yy_buf_pos; /* current position in input buffer */
-
- /* Size of input buffer in bytes, not including room for EOB
- * characters.
- */
- yy_size_t yy_buf_size;
-
- /* Number of characters read into yy_ch_buf, not including EOB
- * characters.
- */
- int yy_n_chars;
-
- /* Whether we "own" the buffer - i.e., we know we created it,
- * and can realloc() it to grow it, and should free() it to
- * delete it.
- */
- int yy_is_our_buffer;
-
- /* Whether this is an "interactive" input source; if so, and
- * if we're using stdio for input, then we want to use getc()
- * instead of fread(), to make sure we stop fetching input after
- * each newline.
- */
- int yy_is_interactive;
-
- /* Whether we're considered to be at the beginning of a line.
- * If so, '^' rules will be active on the next match, otherwise
- * not.
- */
- int yy_at_bol;
-
- /* Whether to try to fill the input buffer when we reach the
- * end of it.
- */
- int yy_fill_buffer;
-
- int yy_buffer_status;
-#define YY_BUFFER_NEW 0
-#define YY_BUFFER_NORMAL 1
- /* When an EOF's been seen but there's still some text to process
- * then we mark the buffer as YY_EOF_PENDING, to indicate that we
- * shouldn't try reading from the input source any more. We might
- * still have a bunch of tokens to match, though, because of
- * possible backing-up.
- *
- * When we actually see the EOF, we change the status to "new"
- * (via yyrestart()), so that the user can continue scanning by
- * just pointing yyin at a new input file.
- */
-#define YY_BUFFER_EOF_PENDING 2
- };
-
-static YY_BUFFER_STATE yy_current_buffer = 0;
-
-/* We provide macros for accessing buffer states in case in the
- * future we want to put the buffer states in a more general
- * "scanner state".
- */
-#define YY_CURRENT_BUFFER yy_current_buffer
-
-
-/* yy_hold_char holds the character lost when yytext is formed. */
-static char yy_hold_char;
-
-static int yy_n_chars; /* number of characters read into yy_ch_buf */
-
-
-int yyleng;
-
-/* Points to current character in buffer. */
-static char *yy_c_buf_p = (char *) 0;
-static int yy_init = 1; /* whether we need to initialize */
-static int yy_start = 0; /* start state number */
-
-/* Flag which is used to allow yywrap()'s to do buffer switches
- * instead of setting up a fresh yyin. A bit of a hack ...
- */
-static int yy_did_buffer_switch_on_eof;
-
-void yyrestart YY_PROTO(( FILE *input_file ));
-
-void yy_switch_to_buffer YY_PROTO(( YY_BUFFER_STATE new_buffer ));
-void yy_load_buffer_state YY_PROTO(( void ));
-YY_BUFFER_STATE yy_create_buffer YY_PROTO(( FILE *file, int size ));
-void yy_delete_buffer YY_PROTO(( YY_BUFFER_STATE b ));
-void yy_init_buffer YY_PROTO(( YY_BUFFER_STATE b, FILE *file ));
-void yy_flush_buffer YY_PROTO(( YY_BUFFER_STATE b ));
-#define YY_FLUSH_BUFFER yy_flush_buffer( yy_current_buffer )
-
-YY_BUFFER_STATE yy_scan_buffer YY_PROTO(( char *base, yy_size_t size ));
-YY_BUFFER_STATE yy_scan_string YY_PROTO(( yyconst char *yy_str ));
-YY_BUFFER_STATE yy_scan_bytes YY_PROTO(( yyconst char *bytes, int len ));
-
-static void *yy_flex_alloc YY_PROTO(( yy_size_t ));
-static void *yy_flex_realloc YY_PROTO(( void *, yy_size_t ));
-static void yy_flex_free YY_PROTO(( void * ));
-
-#define yy_new_buffer yy_create_buffer
-
-#define yy_set_interactive(is_interactive) \
- { \
- if ( ! yy_current_buffer ) \
- yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
- yy_current_buffer->yy_is_interactive = is_interactive; \
- }
-
-#define yy_set_bol(at_bol) \
- { \
- if ( ! yy_current_buffer ) \
- yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE ); \
- yy_current_buffer->yy_at_bol = at_bol; \
- }
-
-#define YY_AT_BOL() (yy_current_buffer->yy_at_bol)
-
-
-#define yywrap() 1
-#define YY_SKIP_YYWRAP
-typedef unsigned char YY_CHAR;
-FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
-typedef int yy_state_type;
-extern char *yytext;
-#define yytext_ptr yytext
-
-static yy_state_type yy_get_previous_state YY_PROTO(( void ));
-static yy_state_type yy_try_NUL_trans YY_PROTO(( yy_state_type current_state ));
-static int yy_get_next_buffer YY_PROTO(( void ));
-static void yy_fatal_error YY_PROTO(( yyconst char msg[] ));
-
-/* Done after the current pattern has been matched and before the
- * corresponding action - sets up yytext.
- */
-#define YY_DO_BEFORE_ACTION \
- yytext_ptr = yy_bp; \
- yyleng = (int) (yy_cp - yy_bp); \
- yy_hold_char = *yy_cp; \
- *yy_cp = '\0'; \
- yy_c_buf_p = yy_cp;
-
-#define YY_NUM_RULES 47
-#define YY_END_OF_BUFFER 48
-static yyconst short int yy_accept[89] =
- { 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 48, 46,
- 1, 38, 2, 46, 44, 24, 46, 28, 45, 45,
- 45, 45, 45, 45, 45, 45, 45, 45, 45, 45,
- 46, 13, 4, 3, 14, 16, 18, 17, 1, 22,
- 32, 34, 44, 26, 20, 31, 30, 45, 45, 45,
- 19, 45, 45, 29, 27, 39, 25, 23, 15, 15,
- 21, 45, 35, 45, 36, 13, 12, 5, 6, 10,
- 11, 7, 8, 9, 40, 33, 45, 45, 37, 45,
- 5, 6, 45, 41, 42, 5, 43, 0
- } ;
-
-static yyconst int yy_ec[256] =
- { 0,
- 1, 1, 1, 1, 1, 1, 1, 1, 2, 3,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 2, 4, 5, 1, 1, 1, 6, 1, 1,
- 1, 1, 1, 1, 7, 1, 1, 8, 8, 8,
- 8, 8, 8, 8, 8, 9, 9, 7, 1, 10,
- 11, 12, 1, 1, 13, 13, 13, 14, 13, 13,
- 13, 13, 15, 13, 13, 13, 13, 13, 16, 13,
- 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
- 1, 17, 1, 1, 7, 1, 18, 19, 13, 20,
-
- 21, 22, 23, 13, 24, 13, 13, 25, 26, 27,
- 28, 13, 29, 30, 31, 32, 33, 13, 13, 13,
- 13, 13, 1, 34, 1, 35, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1
- } ;
-
-static yyconst int yy_meta[36] =
- { 0,
- 1, 1, 2, 1, 3, 1, 4, 4, 4, 1,
- 1, 1, 4, 4, 4, 4, 3, 4, 4, 4,
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 4, 4, 4, 1, 1
- } ;
-
-static yyconst short int yy_base[96] =
- { 0,
- 0, 0, 33, 34, 0, 0, 88, 87, 110, 154,
- 38, 31, 154, 103, 35, 97, 34, 96, 0, 31,
- 75, 72, 29, 27, 73, 28, 69, 33, 48, 69,
- 64, 0, 154, 154, 97, 154, 154, 154, 54, 154,
- 154, 154, 56, 154, 154, 154, 154, 0, 38, 77,
- 0, 71, 70, 0, 0, 0, 0, 0, 154, 0,
- 0, 62, 0, 60, 154, 0, 154, 59, 68, 154,
- 154, 154, 154, 154, 0, 0, 61, 70, 0, 69,
- 74, 76, 68, 0, 0, 79, 0, 154, 129, 133,
- 137, 58, 141, 145, 149
-
- } ;
-
-static yyconst short int yy_def[96] =
- { 0,
- 88, 1, 89, 89, 90, 90, 91, 91, 88, 88,
- 88, 88, 88, 88, 88, 88, 88, 88, 92, 92,
- 92, 92, 92, 92, 92, 92, 93, 92, 92, 92,
- 88, 94, 88, 88, 95, 88, 88, 88, 88, 88,
- 88, 88, 88, 88, 88, 88, 88, 92, 92, 92,
- 92, 92, 92, 92, 92, 92, 92, 92, 88, 92,
- 92, 92, 92, 92, 88, 94, 88, 88, 88, 88,
- 88, 88, 88, 88, 92, 92, 92, 92, 92, 92,
- 88, 88, 92, 92, 92, 88, 92, 0, 88, 88,
- 88, 88, 88, 88, 88
-
- } ;
-
-static yyconst short int yy_nxt[190] =
- { 0,
- 10, 11, 11, 12, 13, 14, 10, 15, 15, 16,
- 17, 18, 19, 19, 19, 20, 10, 21, 19, 19,
- 22, 23, 24, 25, 26, 27, 28, 29, 19, 19,
- 19, 30, 19, 31, 10, 33, 33, 34, 34, 39,
- 39, 40, 43, 43, 45, 49, 52, 54, 57, 35,
- 35, 75, 53, 61, 49, 39, 39, 75, 55, 58,
- 62, 48, 49, 43, 43, 41, 81, 82, 46, 59,
- 59, 49, 59, 59, 59, 82, 82, 63, 59, 59,
- 59, 86, 82, 82, 82, 59, 82, 82, 87, 85,
- 84, 83, 80, 79, 78, 77, 76, 65, 64, 56,
-
- 51, 50, 59, 59, 68, 69, 47, 44, 42, 88,
- 38, 38, 88, 88, 88, 70, 88, 88, 71, 88,
- 88, 88, 88, 72, 88, 88, 73, 88, 74, 32,
- 32, 32, 32, 36, 36, 36, 36, 37, 37, 37,
- 37, 60, 88, 60, 60, 66, 88, 88, 66, 67,
- 67, 67, 67, 9, 88, 88, 88, 88, 88, 88,
- 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
- 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
- 88, 88, 88, 88, 88, 88, 88, 88, 88
- } ;
-
-static yyconst short int yy_chk[190] =
- { 0,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 1, 1, 1, 1, 1, 3, 4, 3, 4, 11,
- 11, 12, 15, 15, 17, 20, 23, 24, 26, 3,
- 4, 49, 23, 28, 20, 39, 39, 49, 24, 26,
- 28, 92, 29, 43, 43, 12, 68, 68, 17, 27,
- 27, 29, 27, 27, 27, 69, 69, 29, 27, 27,
- 27, 81, 81, 82, 82, 27, 86, 86, 83, 80,
- 78, 77, 64, 62, 53, 52, 50, 31, 30, 25,
-
- 22, 21, 27, 27, 35, 35, 18, 16, 14, 9,
- 8, 7, 0, 0, 0, 35, 0, 0, 35, 0,
- 0, 0, 0, 35, 0, 0, 35, 0, 35, 89,
- 89, 89, 89, 90, 90, 90, 90, 91, 91, 91,
- 91, 93, 0, 93, 93, 94, 0, 0, 94, 95,
- 95, 95, 95, 88, 88, 88, 88, 88, 88, 88,
- 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
- 88, 88, 88, 88, 88, 88, 88, 88, 88, 88,
- 88, 88, 88, 88, 88, 88, 88, 88, 88
- } ;
-
-static yy_state_type yy_last_accepting_state;
-static char *yy_last_accepting_cpos;
-
-/* The intent behind this definition is that it'll catch
- * any uses of REJECT which flex missed.
- */
-#define REJECT reject_used_but_not_detected
-#define yymore() yymore_used_but_not_detected
-#define YY_MORE_ADJ 0
-#define YY_RESTORE_YY_MORE_OFFSET
-char *yytext;
-#line 1 "ssl_expr_scan.l"
-#define INITIAL 0
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-/* _ _
- * _ __ ___ ___ __| | ___ ___| |
- * | '_ ` _ \ / _ \ / _` | / __/ __| |
- * | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to OpenSSL
- * |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.modssl.org/
- * |_____|
- * ssl_expr_scan.l
- * Expression Scanner
- */
-/* ``Killing for peace is
-like fucking for virginity.''
--- Unknown */
-/* _________________________________________________________________
-**
-** Expression Scanner
-** _________________________________________________________________
-*/
-#line 37 "ssl_expr_scan.l"
-#include "ssl_private.h"
-
-#include "ssl_expr_parse.h"
-
-#define YY_NO_UNPUT 1
-int yyinput(char *buf, int max_size);
-
-#undef YY_INPUT
-#define YY_INPUT(buf,result,max_size) \
- (result = yyinput(buf, max_size))
-
-#define MAX_STR_LEN 2048
-/* %option stack */
-#define YY_NEVER_INTERACTIVE 1
-#define str 1
-
-#define regex 2
-#define regex_flags 3
-
-#line 505 "lex.ssl_expr_yy.c"
-
-/* Macros after this point can all be overridden by user definitions in
- * section 1.
- */
-
-#ifndef YY_SKIP_YYWRAP
-#ifdef __cplusplus
-extern "C" int yywrap YY_PROTO(( void ));
-#else
-extern int yywrap YY_PROTO(( void ));
-#endif
-#endif
-
-#ifndef YY_NO_UNPUT
-static void yyunput YY_PROTO(( int c, char *buf_ptr ));
-#endif
-
-#ifndef yytext_ptr
-static void yy_flex_strncpy YY_PROTO(( char *, yyconst char *, int ));
-#endif
-
-#ifdef YY_NEED_STRLEN
-static int yy_flex_strlen YY_PROTO(( yyconst char * ));
-#endif
-
-#ifndef YY_NO_INPUT
-#ifdef __cplusplus
-static int yyinput YY_PROTO(( void ));
-#else
-static int input YY_PROTO(( void ));
-#endif
-#endif
-
-#if YY_STACK_USED
-static int yy_start_stack_ptr = 0;
-static int yy_start_stack_depth = 0;
-static int *yy_start_stack = 0;
-#ifndef YY_NO_PUSH_STATE
-static void yy_push_state YY_PROTO(( int new_state ));
-#endif
-#ifndef YY_NO_POP_STATE
-static void yy_pop_state YY_PROTO(( void ));
-#endif
-#ifndef YY_NO_TOP_STATE
-static int yy_top_state YY_PROTO(( void ));
-#endif
-
-#else
-#define YY_NO_PUSH_STATE 1
-#define YY_NO_POP_STATE 1
-#define YY_NO_TOP_STATE 1
-#endif
-
-#ifdef YY_MALLOC_DECL
-YY_MALLOC_DECL
-#else
-#if __STDC__
-#ifndef __cplusplus
-#include <stdlib.h>
-#endif
-#else
-/* Just try to get by without declaring the routines. This will fail
- * miserably on non-ANSI systems for which sizeof(size_t) != sizeof(int)
- * or sizeof(void*) != sizeof(int).
- */
-#endif
-#endif
-
-/* Amount of stuff to slurp up with each read. */
-#ifndef YY_READ_BUF_SIZE
-#define YY_READ_BUF_SIZE 8192
-#endif
-
-/* Copy whatever the last rule matched to the standard output. */
-
-#ifndef ECHO
-/* This used to be an fputs(), but since the string might contain NUL's,
- * we now use fwrite().
- */
-#define ECHO (void) fwrite( yytext, yyleng, 1, yyout )
-#endif
-
-/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
- * is returned in "result".
- */
-#ifndef YY_INPUT
-#define YY_INPUT(buf,result,max_size) \
- if ( yy_current_buffer->yy_is_interactive ) \
- { \
- int c = '*', n; \
- for ( n = 0; n < max_size && \
- (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
- buf[n] = (char) c; \
- if ( c == '\n' ) \
- buf[n++] = (char) c; \
- if ( c == EOF && ferror( yyin ) ) \
- YY_FATAL_ERROR( "input in flex scanner failed" ); \
- result = n; \
- } \
- else if ( ((result = fread( buf, 1, max_size, yyin )) == 0) \
- && ferror( yyin ) ) \
- YY_FATAL_ERROR( "input in flex scanner failed" );
-#endif
-
-/* No semi-colon after return; correct usage is to write "yyterminate();" -
- * we don't want an extra ';' after the "return" because that will cause
- * some compilers to complain about unreachable statements.
- */
-#ifndef yyterminate
-#define yyterminate() return YY_NULL
-#endif
-
-/* Number of entries by which start-condition stack grows. */
-#ifndef YY_START_STACK_INCR
-#define YY_START_STACK_INCR 25
-#endif
-
-/* Report a fatal error. */
-#ifndef YY_FATAL_ERROR
-#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
-#endif
-
-/* Default declaration of generated scanner - a define so the user can
- * easily add parameters.
- */
-#ifndef YY_DECL
-#define YY_DECL int yylex YY_PROTO(( void ))
-#endif
-
-/* Code executed at the beginning of each rule, after yytext and yyleng
- * have been set up.
- */
-#ifndef YY_USER_ACTION
-#define YY_USER_ACTION
-#endif
-
-/* Code executed at the end of each rule. */
-#ifndef YY_BREAK
-#define YY_BREAK break;
-#endif
-
-#define YY_RULE_SETUP \
- YY_USER_ACTION
-
-YY_DECL
- {
- register yy_state_type yy_current_state;
- register char *yy_cp, *yy_bp;
- register int yy_act;
-
-#line 58 "ssl_expr_scan.l"
-
-
- char caStr[MAX_STR_LEN];
- char *cpStr = NULL;
- char caRegex[MAX_STR_LEN];
- char *cpRegex = NULL;
- char cRegexDel = NUL;
-
- /*
- * Whitespaces
- */
-#line 668 "lex.ssl_expr_yy.c"
-
- if ( yy_init )
- {
- yy_init = 0;
-
-#ifdef YY_USER_INIT
- YY_USER_INIT;
-#endif
-
- if ( ! yy_start )
- yy_start = 1; /* first start state */
-
- if ( ! yyin )
- yyin = stdin;
-
- if ( ! yyout )
- yyout = stdout;
-
- if ( ! yy_current_buffer )
- yy_current_buffer =
- yy_create_buffer( yyin, YY_BUF_SIZE );
-
- yy_load_buffer_state();
- }
-
- while ( 1 ) /* loops until end-of-file is reached */
- {
- yy_cp = yy_c_buf_p;
-
- /* Support of yytext. */
- *yy_cp = yy_hold_char;
-
- /* yy_bp points to the position in yy_ch_buf of the start of
- * the current run.
- */
- yy_bp = yy_cp;
-
- yy_current_state = yy_start;
-yy_match:
- do
- {
- register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)];
- if ( yy_accept[yy_current_state] )
- {
- yy_last_accepting_state = yy_current_state;
- yy_last_accepting_cpos = yy_cp;
- }
- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
- {
- yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 89 )
- yy_c = yy_meta[(unsigned int) yy_c];
- }
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- ++yy_cp;
- }
- while ( yy_current_state != 88 );
- yy_cp = yy_last_accepting_cpos;
- yy_current_state = yy_last_accepting_state;
-
-yy_find_action:
- yy_act = yy_accept[yy_current_state];
-
- YY_DO_BEFORE_ACTION;
-
-
-do_action: /* This label is used only to access EOF actions. */
-
-
- switch ( yy_act )
- { /* beginning of action switch */
- case 0: /* must back up */
- /* undo the effects of YY_DO_BEFORE_ACTION */
- *yy_cp = yy_hold_char;
- yy_cp = yy_last_accepting_cpos;
- yy_current_state = yy_last_accepting_state;
- goto yy_find_action;
-
-case 1:
-YY_RULE_SETUP
-#line 69 "ssl_expr_scan.l"
-{
- /* NOP */
-}
- YY_BREAK
-/*
- * C-style strings ("...")
- */
-case 2:
-YY_RULE_SETUP
-#line 76 "ssl_expr_scan.l"
-{
- cpStr = caStr;
- BEGIN(str);
-}
- YY_BREAK
-case 3:
-YY_RULE_SETUP
-#line 80 "ssl_expr_scan.l"
-{
- BEGIN(INITIAL);
- *cpStr = NUL;
- yylval.cpVal = apr_pstrdup(ssl_expr_info.pool, caStr);
- return T_STRING;
-}
- YY_BREAK
-case 4:
-YY_RULE_SETUP
-#line 86 "ssl_expr_scan.l"
-{
- yyerror("Unterminated string");
-}
- YY_BREAK
-case 5:
-YY_RULE_SETUP
-#line 89 "ssl_expr_scan.l"
-{
- int result;
-
- (void)sscanf(yytext+1, "%o", &result);
- if (result > 0xff)
- yyerror("Escape sequence out of bound");
- else
- *cpStr++ = result;
-}
- YY_BREAK
-case 6:
-YY_RULE_SETUP
-#line 98 "ssl_expr_scan.l"
-{
- yyerror("Bad escape sequence");
-}
- YY_BREAK
-case 7:
-YY_RULE_SETUP
-#line 101 "ssl_expr_scan.l"
-{ *cpStr++ = '\n'; }
- YY_BREAK
-case 8:
-YY_RULE_SETUP
-#line 102 "ssl_expr_scan.l"
-{ *cpStr++ = '\r'; }
- YY_BREAK
-case 9:
-YY_RULE_SETUP
-#line 103 "ssl_expr_scan.l"
-{ *cpStr++ = '\t'; }
- YY_BREAK
-case 10:
-YY_RULE_SETUP
-#line 104 "ssl_expr_scan.l"
-{ *cpStr++ = '\b'; }
- YY_BREAK
-case 11:
-YY_RULE_SETUP
-#line 105 "ssl_expr_scan.l"
-{ *cpStr++ = '\f'; }
- YY_BREAK
-case 12:
-YY_RULE_SETUP
-#line 106 "ssl_expr_scan.l"
-{
- *cpStr++ = yytext[1];
-}
- YY_BREAK
-case 13:
-YY_RULE_SETUP
-#line 109 "ssl_expr_scan.l"
-{
- char *cp = yytext;
- while (*cp != NUL)
- *cpStr++ = *cp++;
-}
- YY_BREAK
-case 14:
-YY_RULE_SETUP
-#line 114 "ssl_expr_scan.l"
-{
- *cpStr++ = yytext[1];
-}
- YY_BREAK
-/*
- * Regular Expression
- */
-case 15:
-YY_RULE_SETUP
-#line 121 "ssl_expr_scan.l"
-{
- cRegexDel = yytext[1];
- cpRegex = caRegex;
- BEGIN(regex);
-}
- YY_BREAK
-case 16:
-YY_RULE_SETUP
-#line 126 "ssl_expr_scan.l"
-{
- if (yytext[0] == cRegexDel) {
- *cpRegex = NUL;
- BEGIN(regex_flags);
- }
- else {
- *cpRegex++ = yytext[0];
- }
-}
- YY_BREAK
-case 17:
-YY_RULE_SETUP
-#line 135 "ssl_expr_scan.l"
-{
- yylval.cpVal = apr_pstrdup(ssl_expr_info.pool, caRegex);
- BEGIN(INITIAL);
- return T_REGEX_I;
-}
- YY_BREAK
-case 18:
-YY_RULE_SETUP
-#line 140 "ssl_expr_scan.l"
-{
- yylval.cpVal = apr_pstrdup(ssl_expr_info.pool, caRegex);
- yyless(0);
- BEGIN(INITIAL);
- return T_REGEX;
-}
- YY_BREAK
-case YY_STATE_EOF(regex_flags):
-#line 146 "ssl_expr_scan.l"
-{
- yylval.cpVal = apr_pstrdup(ssl_expr_info.pool, caRegex);
- BEGIN(INITIAL);
- return T_REGEX;
-}
- YY_BREAK
-/*
- * Operators
- */
-case 19:
-YY_RULE_SETUP
-#line 155 "ssl_expr_scan.l"
-{ return T_OP_EQ; }
- YY_BREAK
-case 20:
-YY_RULE_SETUP
-#line 156 "ssl_expr_scan.l"
-{ return T_OP_EQ; }
- YY_BREAK
-case 21:
-YY_RULE_SETUP
-#line 157 "ssl_expr_scan.l"
-{ return T_OP_NE; }
- YY_BREAK
-case 22:
-YY_RULE_SETUP
-#line 158 "ssl_expr_scan.l"
-{ return T_OP_NE; }
- YY_BREAK
-case 23:
-YY_RULE_SETUP
-#line 159 "ssl_expr_scan.l"
-{ return T_OP_LT; }
- YY_BREAK
-case 24:
-YY_RULE_SETUP
-#line 160 "ssl_expr_scan.l"
-{ return T_OP_LT; }
- YY_BREAK
-case 25:
-YY_RULE_SETUP
-#line 161 "ssl_expr_scan.l"
-{ return T_OP_LE; }
- YY_BREAK
-case 26:
-YY_RULE_SETUP
-#line 162 "ssl_expr_scan.l"
-{ return T_OP_LE; }
- YY_BREAK
-case 27:
-YY_RULE_SETUP
-#line 163 "ssl_expr_scan.l"
-{ return T_OP_GT; }
- YY_BREAK
-case 28:
-YY_RULE_SETUP
-#line 164 "ssl_expr_scan.l"
-{ return T_OP_GT; }
- YY_BREAK
-case 29:
-YY_RULE_SETUP
-#line 165 "ssl_expr_scan.l"
-{ return T_OP_GE; }
- YY_BREAK
-case 30:
-YY_RULE_SETUP
-#line 166 "ssl_expr_scan.l"
-{ return T_OP_GE; }
- YY_BREAK
-case 31:
-YY_RULE_SETUP
-#line 167 "ssl_expr_scan.l"
-{ return T_OP_REG; }
- YY_BREAK
-case 32:
-YY_RULE_SETUP
-#line 168 "ssl_expr_scan.l"
-{ return T_OP_NRE; }
- YY_BREAK
-case 33:
-YY_RULE_SETUP
-#line 169 "ssl_expr_scan.l"
-{ return T_OP_AND; }
- YY_BREAK
-case 34:
-YY_RULE_SETUP
-#line 170 "ssl_expr_scan.l"
-{ return T_OP_AND; }
- YY_BREAK
-case 35:
-YY_RULE_SETUP
-#line 171 "ssl_expr_scan.l"
-{ return T_OP_OR; }
- YY_BREAK
-case 36:
-YY_RULE_SETUP
-#line 172 "ssl_expr_scan.l"
-{ return T_OP_OR; }
- YY_BREAK
-case 37:
-YY_RULE_SETUP
-#line 173 "ssl_expr_scan.l"
-{ return T_OP_NOT; }
- YY_BREAK
-case 38:
-YY_RULE_SETUP
-#line 174 "ssl_expr_scan.l"
-{ return T_OP_NOT; }
- YY_BREAK
-case 39:
-YY_RULE_SETUP
-#line 175 "ssl_expr_scan.l"
-{ return T_OP_IN; }
- YY_BREAK
-case 40:
-YY_RULE_SETUP
-#line 176 "ssl_expr_scan.l"
-{ return T_OP_OID; }
- YY_BREAK
-/*
- * Functions
- */
-case 41:
-YY_RULE_SETUP
-#line 181 "ssl_expr_scan.l"
-{ return T_FUNC_FILE; }
- YY_BREAK
-/*
- * Specials
- */
-case 42:
-YY_RULE_SETUP
-#line 186 "ssl_expr_scan.l"
-{ return T_TRUE; }
- YY_BREAK
-case 43:
-YY_RULE_SETUP
-#line 187 "ssl_expr_scan.l"
-{ return T_FALSE; }
- YY_BREAK
-/*
- * Digits
- */
-case 44:
-YY_RULE_SETUP
-#line 192 "ssl_expr_scan.l"
-{
- yylval.cpVal = apr_pstrdup(ssl_expr_info.pool, yytext);
- return T_DIGIT;
-}
- YY_BREAK
-/*
- * Identifiers
- */
-case 45:
-YY_RULE_SETUP
-#line 200 "ssl_expr_scan.l"
-{
- yylval.cpVal = apr_pstrdup(ssl_expr_info.pool, yytext);
- return T_ID;
-}
- YY_BREAK
-/*
- * Anything else is returned as is...
- */
-case 46:
-YY_RULE_SETUP
-#line 208 "ssl_expr_scan.l"
-{
- return yytext[0];
-}
- YY_BREAK
-case 47:
-YY_RULE_SETUP
-#line 212 "ssl_expr_scan.l"
-YY_FATAL_ERROR( "flex scanner jammed" );
- YY_BREAK
-#line 1073 "lex.ssl_expr_yy.c"
-case YY_STATE_EOF(INITIAL):
-case YY_STATE_EOF(str):
-case YY_STATE_EOF(regex):
- yyterminate();
-
- case YY_END_OF_BUFFER:
- {
- /* Amount of text matched not including the EOB char. */
- int yy_amount_of_matched_text = (int) (yy_cp - yytext_ptr) - 1;
-
- /* Undo the effects of YY_DO_BEFORE_ACTION. */
- *yy_cp = yy_hold_char;
- YY_RESTORE_YY_MORE_OFFSET
-
- if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_NEW )
- {
- /* We're scanning a new file or input source. It's
- * possible that this happened because the user
- * just pointed yyin at a new source and called
- * yylex(). If so, then we have to assure
- * consistency between yy_current_buffer and our
- * globals. Here is the right place to do so, because
- * this is the first action (other than possibly a
- * back-up) that will match for the new input source.
- */
- yy_n_chars = yy_current_buffer->yy_n_chars;
- yy_current_buffer->yy_input_file = yyin;
- yy_current_buffer->yy_buffer_status = YY_BUFFER_NORMAL;
- }
-
- /* Note that here we test for yy_c_buf_p "<=" to the position
- * of the first EOB in the buffer, since yy_c_buf_p will
- * already have been incremented past the NUL character
- * (since all states make transitions on EOB to the
- * end-of-buffer state). Contrast this with the test
- * in input().
- */
- if ( yy_c_buf_p <= &yy_current_buffer->yy_ch_buf[yy_n_chars] )
- { /* This was really a NUL. */
- yy_state_type yy_next_state;
-
- yy_c_buf_p = yytext_ptr + yy_amount_of_matched_text;
-
- yy_current_state = yy_get_previous_state();
-
- /* Okay, we're now positioned to make the NUL
- * transition. We couldn't have
- * yy_get_previous_state() go ahead and do it
- * for us because it doesn't know how to deal
- * with the possibility of jamming (and we don't
- * want to build jamming into it because then it
- * will run more slowly).
- */
-
- yy_next_state = yy_try_NUL_trans( yy_current_state );
-
- yy_bp = yytext_ptr + YY_MORE_ADJ;
-
- if ( yy_next_state )
- {
- /* Consume the NUL. */
- yy_cp = ++yy_c_buf_p;
- yy_current_state = yy_next_state;
- goto yy_match;
- }
-
- else
- {
- yy_cp = yy_last_accepting_cpos;
- yy_current_state = yy_last_accepting_state;
- goto yy_find_action;
- }
- }
-
- else switch ( yy_get_next_buffer() )
- {
- case EOB_ACT_END_OF_FILE:
- {
- yy_did_buffer_switch_on_eof = 0;
-
- if ( yywrap() )
- {
- /* Note: because we've taken care in
- * yy_get_next_buffer() to have set up
- * yytext, we can now set up
- * yy_c_buf_p so that if some total
- * hoser (like flex itself) wants to
- * call the scanner after we return the
- * YY_NULL, it'll still work - another
- * YY_NULL will get returned.
- */
- yy_c_buf_p = yytext_ptr + YY_MORE_ADJ;
-
- yy_act = YY_STATE_EOF(YY_START);
- goto do_action;
- }
-
- else
- {
- if ( ! yy_did_buffer_switch_on_eof )
- YY_NEW_FILE;
- }
- break;
- }
-
- case EOB_ACT_CONTINUE_SCAN:
- yy_c_buf_p =
- yytext_ptr + yy_amount_of_matched_text;
-
- yy_current_state = yy_get_previous_state();
-
- yy_cp = yy_c_buf_p;
- yy_bp = yytext_ptr + YY_MORE_ADJ;
- goto yy_match;
-
- case EOB_ACT_LAST_MATCH:
- yy_c_buf_p =
- &yy_current_buffer->yy_ch_buf[yy_n_chars];
-
- yy_current_state = yy_get_previous_state();
-
- yy_cp = yy_c_buf_p;
- yy_bp = yytext_ptr + YY_MORE_ADJ;
- goto yy_find_action;
- }
- break;
- }
-
- default:
- YY_FATAL_ERROR(
- "fatal flex scanner internal error--no action found" );
- } /* end of action switch */
- } /* end of scanning one token */
- } /* end of yylex */
-
-
-/* yy_get_next_buffer - try to read in a new buffer
- *
- * Returns a code representing an action:
- * EOB_ACT_LAST_MATCH -
- * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
- * EOB_ACT_END_OF_FILE - end of file
- */
-
-static int yy_get_next_buffer()
- {
- register char *dest = yy_current_buffer->yy_ch_buf;
- register char *source = yytext_ptr;
- register int number_to_move, i;
- int ret_val;
-
- if ( yy_c_buf_p > &yy_current_buffer->yy_ch_buf[yy_n_chars + 1] )
- YY_FATAL_ERROR(
- "fatal flex scanner internal error--end of buffer missed" );
-
- if ( yy_current_buffer->yy_fill_buffer == 0 )
- { /* Don't try to fill the buffer, so this is an EOF. */
- if ( yy_c_buf_p - yytext_ptr - YY_MORE_ADJ == 1 )
- {
- /* We matched a single character, the EOB, so
- * treat this as a final EOF.
- */
- return EOB_ACT_END_OF_FILE;
- }
-
- else
- {
- /* We matched some text prior to the EOB, first
- * process it.
- */
- return EOB_ACT_LAST_MATCH;
- }
- }
-
- /* Try to read more data. */
-
- /* First move last chars to start of buffer. */
- number_to_move = (int) (yy_c_buf_p - yytext_ptr) - 1;
-
- for ( i = 0; i < number_to_move; ++i )
- *(dest++) = *(source++);
-
- if ( yy_current_buffer->yy_buffer_status == YY_BUFFER_EOF_PENDING )
- /* don't do the read, it's not guaranteed to return an EOF,
- * just force an EOF
- */
- yy_current_buffer->yy_n_chars = yy_n_chars = 0;
-
- else
- {
- int num_to_read =
- yy_current_buffer->yy_buf_size - number_to_move - 1;
-
- while ( num_to_read <= 0 )
- { /* Not enough room in the buffer - grow it. */
-#ifdef YY_USES_REJECT
- YY_FATAL_ERROR(
-"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
-#else
-
- /* just a shorter name for the current buffer */
- YY_BUFFER_STATE b = yy_current_buffer;
-
- int yy_c_buf_p_offset =
- (int) (yy_c_buf_p - b->yy_ch_buf);
-
- if ( b->yy_is_our_buffer )
- {
- int new_size = b->yy_buf_size * 2;
-
- if ( new_size <= 0 )
- b->yy_buf_size += b->yy_buf_size / 8;
- else
- b->yy_buf_size *= 2;
-
- b->yy_ch_buf = (char *)
- /* Include room in for 2 EOB chars. */
- yy_flex_realloc( (void *) b->yy_ch_buf,
- b->yy_buf_size + 2 );
- }
- else
- /* Can't grow it, we don't own it. */
- b->yy_ch_buf = 0;
-
- if ( ! b->yy_ch_buf )
- YY_FATAL_ERROR(
- "fatal error - scanner input buffer overflow" );
-
- yy_c_buf_p = &b->yy_ch_buf[yy_c_buf_p_offset];
-
- num_to_read = yy_current_buffer->yy_buf_size -
- number_to_move - 1;
-#endif
- }
-
- if ( num_to_read > YY_READ_BUF_SIZE )
- num_to_read = YY_READ_BUF_SIZE;
-
- /* Read in more data. */
- YY_INPUT( (&yy_current_buffer->yy_ch_buf[number_to_move]),
- yy_n_chars, num_to_read );
-
- yy_current_buffer->yy_n_chars = yy_n_chars;
- }
-
- if ( yy_n_chars == 0 )
- {
- if ( number_to_move == YY_MORE_ADJ )
- {
- ret_val = EOB_ACT_END_OF_FILE;
- yyrestart( yyin );
- }
-
- else
- {
- ret_val = EOB_ACT_LAST_MATCH;
- yy_current_buffer->yy_buffer_status =
- YY_BUFFER_EOF_PENDING;
- }
- }
-
- else
- ret_val = EOB_ACT_CONTINUE_SCAN;
-
- yy_n_chars += number_to_move;
- yy_current_buffer->yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
- yy_current_buffer->yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
-
- yytext_ptr = &yy_current_buffer->yy_ch_buf[0];
-
- return ret_val;
- }
-
-
-/* yy_get_previous_state - get the state just before the EOB char was reached */
-
-static yy_state_type yy_get_previous_state()
- {
- register yy_state_type yy_current_state;
- register char *yy_cp;
-
- yy_current_state = yy_start;
-
- for ( yy_cp = yytext_ptr + YY_MORE_ADJ; yy_cp < yy_c_buf_p; ++yy_cp )
- {
- register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1);
- if ( yy_accept[yy_current_state] )
- {
- yy_last_accepting_state = yy_current_state;
- yy_last_accepting_cpos = yy_cp;
- }
- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
- {
- yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 89 )
- yy_c = yy_meta[(unsigned int) yy_c];
- }
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- }
-
- return yy_current_state;
- }
-
-
-/* yy_try_NUL_trans - try to make a transition on the NUL character
- *
- * synopsis
- * next_state = yy_try_NUL_trans( current_state );
- */
-
-#ifdef YY_USE_PROTOS
-static yy_state_type yy_try_NUL_trans( yy_state_type yy_current_state )
-#else
-static yy_state_type yy_try_NUL_trans( yy_current_state )
-yy_state_type yy_current_state;
-#endif
- {
- register int yy_is_jam;
- register char *yy_cp = yy_c_buf_p;
-
- register YY_CHAR yy_c = 1;
- if ( yy_accept[yy_current_state] )
- {
- yy_last_accepting_state = yy_current_state;
- yy_last_accepting_cpos = yy_cp;
- }
- while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
- {
- yy_current_state = (int) yy_def[yy_current_state];
- if ( yy_current_state >= 89 )
- yy_c = yy_meta[(unsigned int) yy_c];
- }
- yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
- yy_is_jam = (yy_current_state == 88);
-
- return yy_is_jam ? 0 : yy_current_state;
- }
-
-
-#ifndef YY_NO_UNPUT
-#ifdef YY_USE_PROTOS
-static void yyunput( int c, register char *yy_bp )
-#else
-static void yyunput( c, yy_bp )
-int c;
-register char *yy_bp;
-#endif
- {
- register char *yy_cp = yy_c_buf_p;
-
- /* undo effects of setting up yytext */
- *yy_cp = yy_hold_char;
-
- if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
- { /* need to shift things up to make room */
- /* +2 for EOB chars. */
- register int number_to_move = yy_n_chars + 2;
- register char *dest = &yy_current_buffer->yy_ch_buf[
- yy_current_buffer->yy_buf_size + 2];
- register char *source =
- &yy_current_buffer->yy_ch_buf[number_to_move];
-
- while ( source > yy_current_buffer->yy_ch_buf )
- *--dest = *--source;
-
- yy_cp += (int) (dest - source);
- yy_bp += (int) (dest - source);
- yy_current_buffer->yy_n_chars =
- yy_n_chars = yy_current_buffer->yy_buf_size;
-
- if ( yy_cp < yy_current_buffer->yy_ch_buf + 2 )
- YY_FATAL_ERROR( "flex scanner push-back overflow" );
- }
-
- *--yy_cp = (char) c;
-
-
- yytext_ptr = yy_bp;
- yy_hold_char = *yy_cp;
- yy_c_buf_p = yy_cp;
- }
-#endif /* ifndef YY_NO_UNPUT */
-
-
-#ifdef __cplusplus
-static int yyinput()
-#else
-static int input()
-#endif
- {
- int c;
-
- *yy_c_buf_p = yy_hold_char;
-
- if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
- {
- /* yy_c_buf_p now points to the character we want to return.
- * If this occurs *before* the EOB characters, then it's a
- * valid NUL; if not, then we've hit the end of the buffer.
- */
- if ( yy_c_buf_p < &yy_current_buffer->yy_ch_buf[yy_n_chars] )
- /* This was really a NUL. */
- *yy_c_buf_p = '\0';
-
- else
- { /* need more input */
- int offset = yy_c_buf_p - yytext_ptr;
- ++yy_c_buf_p;
-
- switch ( yy_get_next_buffer() )
- {
- case EOB_ACT_LAST_MATCH:
- /* This happens because yy_g_n_b()
- * sees that we've accumulated a
- * token and flags that we need to
- * try matching the token before
- * proceeding. But for input(),
- * there's no matching to consider.
- * So convert the EOB_ACT_LAST_MATCH
- * to EOB_ACT_END_OF_FILE.
- */
-
- /* Reset buffer status. */
- yyrestart( yyin );
-
- /* fall through */
-
- case EOB_ACT_END_OF_FILE:
- {
- if ( yywrap() )
- return EOF;
-
- if ( ! yy_did_buffer_switch_on_eof )
- YY_NEW_FILE;
-#ifdef __cplusplus
- return yyinput();
-#else
- return input();
-#endif
- }
-
- case EOB_ACT_CONTINUE_SCAN:
- yy_c_buf_p = yytext_ptr + offset;
- break;
- }
- }
- }
-
- c = *(unsigned char *) yy_c_buf_p; /* cast for 8-bit char's */
- *yy_c_buf_p = '\0'; /* preserve yytext */
- yy_hold_char = *++yy_c_buf_p;
-
-
- return c;
- }
-
-
-#ifdef YY_USE_PROTOS
-void yyrestart( FILE *input_file )
-#else
-void yyrestart( input_file )
-FILE *input_file;
-#endif
- {
- if ( ! yy_current_buffer )
- yy_current_buffer = yy_create_buffer( yyin, YY_BUF_SIZE );
-
- yy_init_buffer( yy_current_buffer, input_file );
- yy_load_buffer_state();
- }
-
-
-#ifdef YY_USE_PROTOS
-void yy_switch_to_buffer( YY_BUFFER_STATE new_buffer )
-#else
-void yy_switch_to_buffer( new_buffer )
-YY_BUFFER_STATE new_buffer;
-#endif
- {
- if ( yy_current_buffer == new_buffer )
- return;
-
- if ( yy_current_buffer )
- {
- /* Flush out information for old buffer. */
- *yy_c_buf_p = yy_hold_char;
- yy_current_buffer->yy_buf_pos = yy_c_buf_p;
- yy_current_buffer->yy_n_chars = yy_n_chars;
- }
-
- yy_current_buffer = new_buffer;
- yy_load_buffer_state();
-
- /* We don't actually know whether we did this switch during
- * EOF (yywrap()) processing, but the only time this flag
- * is looked at is after yywrap() is called, so it's safe
- * to go ahead and always set it.
- */
- yy_did_buffer_switch_on_eof = 1;
- }
-
-
-#ifdef YY_USE_PROTOS
-void yy_load_buffer_state( void )
-#else
-void yy_load_buffer_state()
-#endif
- {
- yy_n_chars = yy_current_buffer->yy_n_chars;
- yytext_ptr = yy_c_buf_p = yy_current_buffer->yy_buf_pos;
- yyin = yy_current_buffer->yy_input_file;
- yy_hold_char = *yy_c_buf_p;
- }
-
-
-#ifdef YY_USE_PROTOS
-YY_BUFFER_STATE yy_create_buffer( FILE *file, int size )
-#else
-YY_BUFFER_STATE yy_create_buffer( file, size )
-FILE *file;
-int size;
-#endif
- {
- YY_BUFFER_STATE b;
-
- b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
- if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
-
- b->yy_buf_size = size;
-
- /* yy_ch_buf has to be 2 characters longer than the size given because
- * we need to put in 2 end-of-buffer characters.
- */
- b->yy_ch_buf = (char *) yy_flex_alloc( b->yy_buf_size + 2 );
- if ( ! b->yy_ch_buf )
- YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
-
- b->yy_is_our_buffer = 1;
-
- yy_init_buffer( b, file );
-
- return b;
- }
-
-
-#ifdef YY_USE_PROTOS
-void yy_delete_buffer( YY_BUFFER_STATE b )
-#else
-void yy_delete_buffer( b )
-YY_BUFFER_STATE b;
-#endif
- {
- if ( ! b )
- return;
-
- if ( b == yy_current_buffer )
- yy_current_buffer = (YY_BUFFER_STATE) 0;
-
- if ( b->yy_is_our_buffer )
- yy_flex_free( (void *) b->yy_ch_buf );
-
- yy_flex_free( (void *) b );
- }
-
-
-#ifndef YY_ALWAYS_INTERACTIVE
-#ifndef YY_NEVER_INTERACTIVE
-extern int isatty YY_PROTO(( int ));
-#endif
-#endif
-
-#ifdef YY_USE_PROTOS
-void yy_init_buffer( YY_BUFFER_STATE b, FILE *file )
-#else
-void yy_init_buffer( b, file )
-YY_BUFFER_STATE b;
-FILE *file;
-#endif
-
-
- {
- yy_flush_buffer( b );
-
- b->yy_input_file = file;
- b->yy_fill_buffer = 1;
-
-#if YY_ALWAYS_INTERACTIVE
- b->yy_is_interactive = 1;
-#else
-#if YY_NEVER_INTERACTIVE
- b->yy_is_interactive = 0;
-#else
- b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
-#endif
-#endif
- }
-
-
-#ifdef YY_USE_PROTOS
-void yy_flush_buffer( YY_BUFFER_STATE b )
-#else
-void yy_flush_buffer( b )
-YY_BUFFER_STATE b;
-#endif
-
- {
- if ( ! b )
- return;
-
- b->yy_n_chars = 0;
-
- /* We always need two end-of-buffer characters. The first causes
- * a transition to the end-of-buffer state. The second causes
- * a jam in that state.
- */
- b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
- b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
-
- b->yy_buf_pos = &b->yy_ch_buf[0];
-
- b->yy_at_bol = 1;
- b->yy_buffer_status = YY_BUFFER_NEW;
-
- if ( b == yy_current_buffer )
- yy_load_buffer_state();
- }
-
-
-#ifndef YY_NO_SCAN_BUFFER
-#ifdef YY_USE_PROTOS
-YY_BUFFER_STATE yy_scan_buffer( char *base, yy_size_t size )
-#else
-YY_BUFFER_STATE yy_scan_buffer( base, size )
-char *base;
-yy_size_t size;
-#endif
- {
- YY_BUFFER_STATE b;
-
- if ( size < 2 ||
- base[size-2] != YY_END_OF_BUFFER_CHAR ||
- base[size-1] != YY_END_OF_BUFFER_CHAR )
- /* They forgot to leave room for the EOB's. */
- return 0;
-
- b = (YY_BUFFER_STATE) yy_flex_alloc( sizeof( struct yy_buffer_state ) );
- if ( ! b )
- YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
-
- b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
- b->yy_buf_pos = b->yy_ch_buf = base;
- b->yy_is_our_buffer = 0;
- b->yy_input_file = 0;
- b->yy_n_chars = b->yy_buf_size;
- b->yy_is_interactive = 0;
- b->yy_at_bol = 1;
- b->yy_fill_buffer = 0;
- b->yy_buffer_status = YY_BUFFER_NEW;
-
- yy_switch_to_buffer( b );
-
- return b;
- }
-#endif
-
-
-#ifndef YY_NO_SCAN_STRING
-#ifdef YY_USE_PROTOS
-YY_BUFFER_STATE yy_scan_string( yyconst char *yy_str )
-#else
-YY_BUFFER_STATE yy_scan_string( yy_str )
-yyconst char *yy_str;
-#endif
- {
- int len;
- for ( len = 0; yy_str[len]; ++len )
- ;
-
- return yy_scan_bytes( yy_str, len );
- }
-#endif
-
-
-#ifndef YY_NO_SCAN_BYTES
-#ifdef YY_USE_PROTOS
-YY_BUFFER_STATE yy_scan_bytes( yyconst char *bytes, int len )
-#else
-YY_BUFFER_STATE yy_scan_bytes( bytes, len )
-yyconst char *bytes;
-int len;
-#endif
- {
- YY_BUFFER_STATE b;
- char *buf;
- yy_size_t n;
- int i;
-
- /* Get memory for full buffer, including space for trailing EOB's. */
- n = len + 2;
- buf = (char *) yy_flex_alloc( n );
- if ( ! buf )
- YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
-
- for ( i = 0; i < len; ++i )
- buf[i] = bytes[i];
-
- buf[len] = buf[len+1] = YY_END_OF_BUFFER_CHAR;
-
- b = yy_scan_buffer( buf, n );
- if ( ! b )
- YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
-
- /* It's okay to grow etc. this buffer, and we should throw it
- * away when we're done.
- */
- b->yy_is_our_buffer = 1;
-
- return b;
- }
-#endif
-
-
-#ifndef YY_NO_PUSH_STATE
-#ifdef YY_USE_PROTOS
-static void yy_push_state( int new_state )
-#else
-static void yy_push_state( new_state )
-int new_state;
-#endif
- {
- if ( yy_start_stack_ptr >= yy_start_stack_depth )
- {
- yy_size_t new_size;
-
- yy_start_stack_depth += YY_START_STACK_INCR;
- new_size = yy_start_stack_depth * sizeof( int );
-
- if ( ! yy_start_stack )
- yy_start_stack = (int *) yy_flex_alloc( new_size );
-
- else
- yy_start_stack = (int *) yy_flex_realloc(
- (void *) yy_start_stack, new_size );
-
- if ( ! yy_start_stack )
- YY_FATAL_ERROR(
- "out of memory expanding start-condition stack" );
- }
-
- yy_start_stack[yy_start_stack_ptr++] = YY_START;
-
- BEGIN(new_state);
- }
-#endif
-
-
-#ifndef YY_NO_POP_STATE
-static void yy_pop_state()
- {
- if ( --yy_start_stack_ptr < 0 )
- YY_FATAL_ERROR( "start-condition stack underflow" );
-
- BEGIN(yy_start_stack[yy_start_stack_ptr]);
- }
-#endif
-
-
-#ifndef YY_NO_TOP_STATE
-static int yy_top_state()
- {
- return yy_start_stack[yy_start_stack_ptr - 1];
- }
-#endif
-
-#ifndef YY_EXIT_FAILURE
-#define YY_EXIT_FAILURE 2
-#endif
-
-#ifdef YY_USE_PROTOS
-static void yy_fatal_error( yyconst char msg[] )
-#else
-static void yy_fatal_error( msg )
-char msg[];
-#endif
- {
- (void) fprintf( stderr, "%s\n", msg );
- exit( YY_EXIT_FAILURE );
- }
-
-
-
-/* Redefine yyless() so it works in section 3 code. */
-
-#undef yyless
-#define yyless(n) \
- do \
- { \
- /* Undo effects of setting up yytext. */ \
- yytext[yyleng] = yy_hold_char; \
- yy_c_buf_p = yytext + n; \
- yy_hold_char = *yy_c_buf_p; \
- *yy_c_buf_p = '\0'; \
- yyleng = n; \
- } \
- while ( 0 )
-
-
-/* Internal utility routines. */
-
-#ifndef yytext_ptr
-#ifdef YY_USE_PROTOS
-static void yy_flex_strncpy( char *s1, yyconst char *s2, int n )
-#else
-static void yy_flex_strncpy( s1, s2, n )
-char *s1;
-yyconst char *s2;
-int n;
-#endif
- {
- register int i;
- for ( i = 0; i < n; ++i )
- s1[i] = s2[i];
- }
-#endif
-
-#ifdef YY_NEED_STRLEN
-#ifdef YY_USE_PROTOS
-static int yy_flex_strlen( yyconst char *s )
-#else
-static int yy_flex_strlen( s )
-yyconst char *s;
-#endif
- {
- register int n;
- for ( n = 0; s[n]; ++n )
- ;
-
- return n;
- }
-#endif
-
-
-#ifdef YY_USE_PROTOS
-static void *yy_flex_alloc( yy_size_t size )
-#else
-static void *yy_flex_alloc( size )
-yy_size_t size;
-#endif
- {
- return (void *) malloc( size );
- }
-
-#ifdef YY_USE_PROTOS
-static void *yy_flex_realloc( void *ptr, yy_size_t size )
-#else
-static void *yy_flex_realloc( ptr, size )
-void *ptr;
-yy_size_t size;
-#endif
- {
- /* The cast to (char *) in the following accommodates both
- * implementations that use char* generic pointers, and those
- * that use void* generic pointers. It works with the latter
- * because both ANSI C and C++ allow castless assignment from
- * any pointer type to void*, and deal with argument conversions
- * as though doing an assignment.
- */
- return (void *) realloc( (char *) ptr, size );
- }
-
-#ifdef YY_USE_PROTOS
-static void yy_flex_free( void *ptr )
-#else
-static void yy_flex_free( ptr )
-void *ptr;
-#endif
- {
- free( ptr );
- }
-
-#if YY_MAIN
-int main()
- {
- yylex();
- return 0;
- }
-#endif
-#line 212 "ssl_expr_scan.l"
-
-
-int yyinput(char *buf, int max_size)
-{
- int n;
-
- if ((n = MIN(max_size, ssl_expr_info.inputbuf
- + ssl_expr_info.inputlen
- - ssl_expr_info.inputptr)) <= 0)
- return YY_NULL;
- memcpy(buf, ssl_expr_info.inputptr, n);
- ssl_expr_info.inputptr += n;
- return n;
-}
-
diff --git a/modules/ssl/ssl_expr_scan.l b/modules/ssl/ssl_expr_scan.l
deleted file mode 100644
index 6c720523..00000000
--- a/modules/ssl/ssl_expr_scan.l
+++ /dev/null
@@ -1,226 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* _ _
- * _ __ ___ ___ __| | ___ ___| |
- * | '_ ` _ \ / _ \ / _` | / __/ __| |
- * | | | | | | (_) | (_| | \__ \__ \ | mod_ssl - Apache Interface to OpenSSL
- * |_| |_| |_|\___/ \__,_|___|___/___/_| http://www.modssl.org/
- * |_____|
- * ssl_expr_scan.l
- * Expression Scanner
- */
- /* ``Killing for peace is
- like fucking for virginity.''
- -- Unknown */
-
-/* _________________________________________________________________
-**
-** Expression Scanner
-** _________________________________________________________________
-*/
-
-%{
-#include "ssl_private.h"
-
-#include "ssl_expr_parse.h"
-
-#define YY_NO_UNPUT 1
-int yyinput(char *buf, int max_size);
-
-#undef YY_INPUT
-#define YY_INPUT(buf,result,max_size) \
- (result = yyinput(buf, max_size))
-
-#define MAX_STR_LEN 2048
-%}
-
-%pointer
-/* %option stack */
-%option never-interactive
-%option noyywrap
-%x str
-%x regex regex_flags
-
-%%
-
- char caStr[MAX_STR_LEN];
- char *cpStr = NULL;
- char caRegex[MAX_STR_LEN];
- char *cpRegex = NULL;
- char cRegexDel = NUL;
-
- /*
- * Whitespaces
- */
-[ \t\n]+ {
- /* NOP */
-}
-
- /*
- * C-style strings ("...")
- */
-\" {
- cpStr = caStr;
- BEGIN(str);
-}
-<str>\" {
- BEGIN(INITIAL);
- *cpStr = NUL;
- yylval.cpVal = apr_pstrdup(ssl_expr_info.pool, caStr);
- return T_STRING;
-}
-<str>\n {
- yyerror("Unterminated string");
-}
-<str>\\[0-7]{1,3} {
- int result;
-
- (void)sscanf(yytext+1, "%o", &result);
- if (result > 0xff)
- yyerror("Escape sequence out of bound");
- else
- *cpStr++ = result;
-}
-<str>\\[0-9]+ {
- yyerror("Bad escape sequence");
-}
-<str>\\n { *cpStr++ = '\n'; }
-<str>\\r { *cpStr++ = '\r'; }
-<str>\\t { *cpStr++ = '\t'; }
-<str>\\b { *cpStr++ = '\b'; }
-<str>\\f { *cpStr++ = '\f'; }
-<str>\\(.|\n) {
- *cpStr++ = yytext[1];
-}
-<str>[^\\\n\"]+ {
- char *cp = yytext;
- while (*cp != NUL)
- *cpStr++ = *cp++;
-}
-<str>. {
- *cpStr++ = yytext[1];
-}
-
- /*
- * Regular Expression
- */
-"m". {
- cRegexDel = yytext[1];
- cpRegex = caRegex;
- BEGIN(regex);
-}
-<regex>.|\n {
- if (yytext[0] == cRegexDel) {
- *cpRegex = NUL;
- BEGIN(regex_flags);
- }
- else {
- *cpRegex++ = yytext[0];
- }
-}
-<regex_flags>i {
- yylval.cpVal = apr_pstrdup(ssl_expr_info.pool, caRegex);
- BEGIN(INITIAL);
- return T_REGEX_I;
-}
-<regex_flags>.|\n {
- yylval.cpVal = apr_pstrdup(ssl_expr_info.pool, caRegex);
- yyless(0);
- BEGIN(INITIAL);
- return T_REGEX;
-}
-<regex_flags><<EOF>> {
- yylval.cpVal = apr_pstrdup(ssl_expr_info.pool, caRegex);
- BEGIN(INITIAL);
- return T_REGEX;
-}
-
- /*
- * Operators
- */
-"eq" { return T_OP_EQ; }
-"==" { return T_OP_EQ; }
-"ne" { return T_OP_NE; }
-"!=" { return T_OP_NE; }
-"lt" { return T_OP_LT; }
-"<" { return T_OP_LT; }
-"le" { return T_OP_LE; }
-"<=" { return T_OP_LE; }
-"gt" { return T_OP_GT; }
-">" { return T_OP_GT; }
-"ge" { return T_OP_GE; }
-">=" { return T_OP_GE; }
-"=~" { return T_OP_REG; }
-"!~" { return T_OP_NRE; }
-"and" { return T_OP_AND; }
-"&&" { return T_OP_AND; }
-"or" { return T_OP_OR; }
-"||" { return T_OP_OR; }
-"not" { return T_OP_NOT; }
-"!" { return T_OP_NOT; }
-"in" { return T_OP_IN; }
-[Oo][Ii][Dd] { return T_OP_OID; }
-
- /*
- * Functions
- */
-"file" { return T_FUNC_FILE; }
-
- /*
- * Specials
- */
-"true" { return T_TRUE; }
-"false" { return T_FALSE; }
-
- /*
- * Digits
- */
-[0-9]+ {
- yylval.cpVal = apr_pstrdup(ssl_expr_info.pool, yytext);
- return T_DIGIT;
-}
-
- /*
- * Identifiers
- */
-[a-zA-Z][a-zA-Z0-9_:-]* {
- yylval.cpVal = apr_pstrdup(ssl_expr_info.pool, yytext);
- return T_ID;
-}
-
- /*
- * Anything else is returned as is...
- */
-.|\n {
- return yytext[0];
-}
-
-%%
-
-int yyinput(char *buf, int max_size)
-{
- int n;
-
- if ((n = MIN(max_size, ssl_expr_info.inputbuf
- + ssl_expr_info.inputlen
- - ssl_expr_info.inputptr)) <= 0)
- return YY_NULL;
- memcpy(buf, ssl_expr_info.inputptr, n);
- ssl_expr_info.inputptr += n;
- return n;
-}
-
diff --git a/modules/ssl/ssl_private.h b/modules/ssl/ssl_private.h
index 15deb8f1..0ed6e254 100644
--- a/modules/ssl/ssl_private.h
+++ b/modules/ssl/ssl_private.h
@@ -18,7 +18,7 @@
#define SSL_PRIVATE_H
/**
- * @file ssl_private.h
+ * @file ssl_private.h
* @brief Internal interfaces private to mod_ssl.
*
* @defgroup MOD_SSL_PRIVATE Private
@@ -39,47 +39,146 @@
#include "util_script.h"
#include "util_filter.h"
#include "util_ebcdic.h"
-#include "mpm.h"
+#include "util_mutex.h"
#include "apr.h"
#include "apr_strings.h"
#define APR_WANT_STRFUNC
+#define APR_WANT_MEMFUNC
#include "apr_want.h"
#include "apr_tables.h"
#include "apr_lib.h"
#include "apr_fnmatch.h"
#include "apr_strings.h"
-#include "apr_dbm.h"
-#include "apr_rmm.h"
-#include "apr_shm.h"
#include "apr_global_mutex.h"
#include "apr_optional.h"
+#include "ap_socache.h"
+#include "mod_auth.h"
-#define MOD_SSL_VERSION AP_SERVER_BASEREVISION
-
-/** mod_ssl headers */
-#include "ssl_toolkit_compat.h"
-#include "ssl_expr.h"
-#include "ssl_util_ssl.h"
-
-/** The #ifdef macros are only defined AFTER including the above
+/* The #ifdef macros are only defined AFTER including the above
* therefore we cannot include these system files at the top :-(
*/
+#ifdef APR_HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
#if APR_HAVE_SYS_TIME_H
#include <sys/time.h>
#endif
#if APR_HAVE_UNISTD_H
-#include <unistd.h> /** needed for STDIN_FILENO et.al., at least on FreeBSD */
+#include <unistd.h> /* needed for STDIN_FILENO et.al., at least on FreeBSD */
#endif
-/**
- * Provide reasonable default for some defines
- */
#ifndef FALSE
-#define FALSE (0)
+#define FALSE 0
#endif
+
#ifndef TRUE
-#define TRUE (!FALSE)
+#define TRUE !FALSE
+#endif
+
+#ifndef BOOL
+#define BOOL unsigned int
+#endif
+
+#include "ap_expr.h"
+
+/* OpenSSL headers */
+#include <openssl/ssl.h>
+#include <openssl/err.h>
+#include <openssl/x509.h>
+#include <openssl/pem.h>
+#include <openssl/crypto.h>
+#include <openssl/evp.h>
+#include <openssl/rand.h>
+#include <openssl/x509v3.h>
+#include <openssl/x509_vfy.h>
+#include <openssl/ocsp.h>
+
+/* Avoid tripping over an engine build installed globally and detected
+ * when the user points at an explicit non-engine flavor of OpenSSL
+ */
+#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
+#include <openssl/engine.h>
#endif
+
+#if (OPENSSL_VERSION_NUMBER < 0x0090700f)
+#error mod_ssl requires OpenSSL 0.9.7 or later
+#endif
+
+/* ...shifting sands of OpenSSL... */
+#if (OPENSSL_VERSION_NUMBER >= 0x0090707f)
+#define MODSSL_D2I_SSL_SESSION_CONST const
+#else
+#define MODSSL_D2I_SSL_SESSION_CONST
+#endif
+
+#if (OPENSSL_VERSION_NUMBER >= 0x00908000)
+#define HAVE_GENERATE_EX
+#define MODSSL_D2I_ASN1_type_bytes_CONST const
+#define MODSSL_D2I_PrivateKey_CONST const
+#define MODSSL_D2I_X509_CONST const
+#else
+#define MODSSL_D2I_ASN1_type_bytes_CONST
+#define MODSSL_D2I_PrivateKey_CONST
+#define MODSSL_D2I_X509_CONST
+#endif
+
+#if OPENSSL_VERSION_NUMBER >= 0x00908080 && !defined(OPENSSL_NO_OCSP) \
+ && !defined(OPENSSL_NO_TLSEXT)
+#define HAVE_OCSP_STAPLING
+#if (OPENSSL_VERSION_NUMBER < 0x10000000)
+#define sk_OPENSSL_STRING_pop sk_pop
+#endif
+#endif
+
+#if (OPENSSL_VERSION_NUMBER >= 0x009080a0) && defined(OPENSSL_FIPS)
+#define HAVE_FIPS
+#endif
+
+#if (OPENSSL_VERSION_NUMBER >= 0x10000000)
+#define MODSSL_SSL_CIPHER_CONST const
+#define MODSSL_SSL_METHOD_CONST const
+#else
+#define MODSSL_SSL_CIPHER_CONST
+#define MODSSL_SSL_METHOD_CONST
+/* ECC support came along in OpenSSL 1.0.0 */
+#define OPENSSL_NO_EC
+#endif
+
+#ifndef PEM_F_DEF_CALLBACK
+#ifdef PEM_F_PEM_DEF_CALLBACK
+/** In OpenSSL 0.9.8 PEM_F_DEF_CALLBACK was renamed */
+#define PEM_F_DEF_CALLBACK PEM_F_PEM_DEF_CALLBACK
+#endif
+#endif
+
+#ifndef OPENSSL_NO_TLSEXT
+#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
+#define OPENSSL_NO_TLSEXT
+#endif
+#endif
+
+#ifndef OPENSSL_NO_TLSEXT
+#ifdef SSL_CTRL_SET_TLSEXT_TICKET_KEY_CB
+#define HAVE_TLS_SESSION_TICKETS
+#define TLSEXT_TICKET_KEY_LEN 48
+#ifndef tlsext_tick_md
+#ifdef OPENSSL_NO_SHA256
+#define tlsext_tick_md EVP_sha1
+#else
+#define tlsext_tick_md EVP_sha256
+#endif
+#endif
+#endif
+#endif
+
+/* mod_ssl headers */
+#include "ssl_util_ssl.h"
+
+APLOG_USE_MODULE(ssl);
+
+/*
+ * Provide reasonable default for some defines
+ */
#ifndef PFALSE
#define PFALSE ((void *)FALSE)
#endif
@@ -100,9 +199,6 @@
/**
* Provide reasonable defines for some types
*/
-#ifndef BOOL
-#define BOOL unsigned int
-#endif
#ifndef UCHAR
#define UCHAR unsigned char
#endif
@@ -149,27 +245,14 @@ ap_set_module_config(c->conn_config, &ssl_module, val)
#define DEFAULT_RENEG_BUFFER_SIZE (128 * 1024)
#endif
-/**
- * Support for MM library
- */
-#define SSL_MM_FILE_MODE ( APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD )
-
-/**
- * Support for DBM library
- */
-#define SSL_DBM_FILE_MODE ( APR_UREAD | APR_UWRITE | APR_GREAD | APR_WREAD )
-
-#if !defined(SSL_DBM_FILE_SUFFIX_DIR) && !defined(SSL_DBM_FILE_SUFFIX_PAG)
-#if defined(DBM_SUFFIX)
-#define SSL_DBM_FILE_SUFFIX_DIR DBM_SUFFIX
-#define SSL_DBM_FILE_SUFFIX_PAG DBM_SUFFIX
-#elif defined(__FreeBSD__) || (defined(DB_LOCK) && defined(DB_SHMEM))
-#define SSL_DBM_FILE_SUFFIX_DIR ".db"
-#define SSL_DBM_FILE_SUFFIX_PAG ".db"
-#else
-#define SSL_DBM_FILE_SUFFIX_DIR ".dir"
-#define SSL_DBM_FILE_SUFFIX_PAG ".pag"
+/* Default for OCSP response validity */
+#ifndef DEFAULT_OCSP_MAX_SKEW
+#define DEFAULT_OCSP_MAX_SKEW (60 * 5)
#endif
+
+/* Default timeout for OCSP queries */
+#ifndef DEFAULT_OCSP_TIMEOUT
+#define DEFAULT_OCSP_TIMEOUT 10
#endif
/**
@@ -181,11 +264,21 @@ typedef int ssl_algo_t;
#define SSL_ALGO_UNKNOWN (0)
#define SSL_ALGO_RSA (1<<0)
#define SSL_ALGO_DSA (1<<1)
+#ifndef OPENSSL_NO_EC
+#define SSL_ALGO_ECC (1<<2)
+#define SSL_ALGO_ALL (SSL_ALGO_RSA|SSL_ALGO_DSA|SSL_ALGO_ECC)
+#else
#define SSL_ALGO_ALL (SSL_ALGO_RSA|SSL_ALGO_DSA)
+#endif
#define SSL_AIDX_RSA (0)
#define SSL_AIDX_DSA (1)
+#ifndef OPENSSL_NO_EC
+#define SSL_AIDX_ECC (2)
+#define SSL_AIDX_MAX (3)
+#else
#define SSL_AIDX_MAX (2)
+#endif
/**
@@ -208,7 +301,7 @@ typedef int ssl_algo_t;
#define SSL_OPT_FAKEBASICAUTH (1<<4)
#define SSL_OPT_STRICTREQUIRE (1<<5)
#define SSL_OPT_OPTRENEGOTIATE (1<<6)
-#define SSL_OPT_ALL (SSL_OPT_STDENVVARS|SSL_OPT_EXPORTCERTDATA|SSL_OPT_FAKEBASICAUTH|SSL_OPT_STRICTREQUIRE|SSL_OPT_OPTRENEGOTIATE)
+#define SSL_OPT_LEGACYDNFORMAT (1<<7)
typedef int ssl_opt_t;
/**
@@ -218,11 +311,7 @@ typedef int ssl_opt_t;
#define SSL_PROTOCOL_SSLV2 (1<<0)
#define SSL_PROTOCOL_SSLV3 (1<<1)
#define SSL_PROTOCOL_TLSV1 (1<<2)
-#ifndef OPENSSL_NO_SSL2
-#define SSL_PROTOCOL_ALL (SSL_PROTOCOL_SSLV2|SSL_PROTOCOL_SSLV3|SSL_PROTOCOL_TLSV1)
-#else
#define SSL_PROTOCOL_ALL (SSL_PROTOCOL_SSLV3|SSL_PROTOCOL_TLSV1)
-#endif
typedef int ssl_proto_t;
/**
@@ -239,10 +328,6 @@ typedef enum {
#define SSL_VERIFY_PEER_STRICT \
(SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT)
-#ifndef X509_V_ERR_CERT_UNTRUSTED
-#define X509_V_ERR_CERT_UNTRUSTED 27
-#endif
-
#define ssl_verify_error_is_optional(errnum) \
((errnum == X509_V_ERR_DEPTH_ZERO_SELF_SIGNED_CERT) \
|| (errnum == X509_V_ERR_SELF_SIGNED_CERT_IN_CHAIN) \
@@ -251,13 +336,23 @@ typedef enum {
|| (errnum == X509_V_ERR_UNABLE_TO_VERIFY_LEAF_SIGNATURE))
/**
+ * CRL checking modes
+ */
+typedef enum {
+ SSL_CRLCHECK_UNSET = UNSET,
+ SSL_CRLCHECK_NONE = 0,
+ SSL_CRLCHECK_LEAF = 1,
+ SSL_CRLCHECK_CHAIN = 2
+} ssl_crlcheck_t;
+
+/**
* Define the SSL pass phrase dialog types
*/
typedef enum {
SSL_PPTYPE_UNSET = UNSET,
SSL_PPTYPE_BUILTIN = 0,
SSL_PPTYPE_FILTER = 1,
- SSL_PPTYPE_PIPE = 2
+ SSL_PPTYPE_PIPE = 2
} ssl_pphrase_t;
/**
@@ -270,42 +365,21 @@ typedef enum {
typedef unsigned int ssl_pathcheck_t;
/**
- * Define the SSL session cache modes and structures
- */
-typedef enum {
- SSL_SCMODE_UNSET = UNSET,
- SSL_SCMODE_NONE = 0,
- SSL_SCMODE_DBM = 1,
- SSL_SCMODE_SHMCB = 3,
- SSL_SCMODE_DC = 4,
- SSL_SCMODE_NONE_NOT_NULL = 5
-} ssl_scmode_t;
-
-/**
- * Define the SSL mutex modes
- */
-typedef enum {
- SSL_MUTEXMODE_UNSET = UNSET,
- SSL_MUTEXMODE_NONE = 0,
- SSL_MUTEXMODE_USED = 1
-} ssl_mutexmode_t;
-
-/**
* Define the SSL enabled state
*/
typedef enum {
SSL_ENABLED_UNSET = UNSET,
SSL_ENABLED_FALSE = 0,
SSL_ENABLED_TRUE = 1,
- SSL_ENABLED_OPTIONAL = 3
+ SSL_ENABLED_OPTIONAL = 3
} ssl_enabled_t;
/**
* Define the SSL requirement structure
*/
typedef struct {
- char *cpExpr;
- ssl_expr *mpExpr;
+ char *cpExpr;
+ ap_expr_info_t *mpExpr;
} ssl_require_t;
/**
@@ -364,7 +438,7 @@ typedef struct {
/* Track the handshake/renegotiation state for the connection so
* that all client-initiated renegotiations can be rejected, as a
* partial fix for CVE-2009-3555. */
- enum {
+ enum {
RENEG_INIT = 0, /* Before initial handshake */
RENEG_REJECT, /* After initial handshake; any client-initiated
* renegotiation should be rejected */
@@ -373,45 +447,93 @@ typedef struct {
RENEG_ABORT /* Renegotiation initiated by client, abort the
* connection */
} reneg_state;
-
+
server_rec *server;
} SSLConnRec;
+/* BIG FAT WARNING: SSLModConfigRec has unusual memory lifetime: it is
+ * allocated out of the "process" pool and only a single such
+ * structure is created and used for the lifetime of the process.
+ * (The process pool is s->process->pool and is stored in the .pPool
+ * field.) Most members of this structure are likewise allocated out
+ * of the process pool, but notably sesscache and sesscache_context
+ * are not.
+ *
+ * The structure is treated as mostly immutable after a single config
+ * parse has completed; the post_config hook (ssl_init_Module) flips
+ * the bFixed flag to true and subsequent invocations of the config
+ * callbacks hence do nothing.
+ *
+ * This odd lifetime strategy is used so that encrypted private keys
+ * can be decrypted once at startup and continue to be used across
+ * subsequent server reloads where the interactive password prompt is
+ * not possible.
+
+ * It is really an ABI nightmare waiting to happen since DSOs are
+ * reloaded across restarts, and nothing prevents the struct type
+ * changing across such reloads, yet the cached structure will be
+ * assumed to match regardless.
+ *
+ * This should really be fixed using a smaller structure which only
+ * stores that which is absolutely necessary (the private keys, maybe
+ * the random seed), and have that structure be strictly ABI-versioned
+ * for safety.
+ */
typedef struct {
pid_t pid;
apr_pool_t *pPool;
BOOL bFixed;
- int nSessionCacheMode;
- char *szSessionCacheDataFile;
- int nSessionCacheDataSize;
- apr_shm_t *pSessionCacheDataMM;
- apr_rmm_t *pSessionCacheDataRMM;
- void *tSessionCacheDataTable;
- ssl_mutexmode_t nMutexMode;
- apr_lockmech_e nMutexMech;
- const char *szMutexFile;
+
+ /* OpenSSL SSL_SESS_CACHE_* flags: */
+ long sesscache_mode;
+
+ /* The configured provider, and associated private data
+ * structure. */
+ const ap_socache_provider_t *sesscache;
+ ap_socache_instance_t *sesscache_context;
+
apr_global_mutex_t *pMutex;
apr_array_header_t *aRandSeed;
apr_hash_t *tVHostKeys;
void *pTmpKeys[SSL_TMP_KEY_MAX];
+
+ /* Two hash tables of pointers to ssl_asn1_t structures. The
+ * structures are used to store certificates and private keys
+ * respectively, in raw DER format (serialized OpenSSL X509 and
+ * PrivateKey structures). The tables are indexed by (vhost-id,
+ * algorithm type) using the function ssl_asn1_table_keyfmt(); for
+ * example the string "vhost.example.com:443:RSA". */
apr_hash_t *tPublicCert;
apr_hash_t *tPrivateKey;
+
#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
const char *szCryptoDevice;
#endif
+
+#ifdef HAVE_OCSP_STAPLING
+ const ap_socache_provider_t *stapling_cache;
+ ap_socache_instance_t *stapling_cache_context;
+ apr_global_mutex_t *stapling_mutex;
+#endif
+
struct {
void *pV1, *pV2, *pV3, *pV4, *pV5, *pV6, *pV7, *pV8, *pV9, *pV10;
} rCtx;
} SSLModConfigRec;
-/** public cert/private key */
+/** Structure representing configured filenames for certs and keys for
+ * a given vhost, and the corresponding in-memory structures once the
+ * files are parsed. */
typedef struct {
- /**
- * server only has 1-2 certs/keys
- * 1 RSA and/or 1 DSA
- */
+ /* Lists of configured certs and keys for this server; from index
+ * 0 up to SSL_AIDX_MAX-1 or the first NULL pointer. Note that
+ * these arrays are NOT indexed by algorithm type, they are simply
+ * unordered lists. */
const char *cert_files[SSL_AIDX_MAX];
const char *key_files[SSL_AIDX_MAX];
+ /* Loaded certs and keys; these arrays ARE indexed by the
+ * algorithm type, i.e. keys[SSL_AIDX_RSA] maps to the RSA
+ * private key. */
X509 *certs[SSL_AIDX_MAX];
EVP_PKEY *keys[SSL_AIDX_MAX];
@@ -425,7 +547,11 @@ typedef struct {
/** proxy can have any number of cert/key pairs */
const char *cert_file;
const char *cert_path;
- STACK_OF(X509_INFO) *certs;
+ const char *ca_cert_file;
+ STACK_OF(X509_INFO) *certs; /* Contains End Entity certs */
+ STACK_OF(X509) **ca_certs; /* Contains ONLY chain certs for
+ * each item in certs.
+ * (ptr to array of ptrs) */
} modssl_pk_proxy_t;
/** stuff related to authentication that can also be per-dir */
@@ -441,6 +567,15 @@ typedef struct {
ssl_verify_t verify_mode;
} modssl_auth_ctx_t;
+#ifdef HAVE_TLS_SESSION_TICKETS
+typedef struct {
+ const char *file_path;
+ unsigned char key_name[16];
+ unsigned char hmac_secret[16];
+ unsigned char aes_key[16];
+} modssl_ticket_key_t;
+#endif
+
typedef struct SSLSrvConfigRec SSLSrvConfigRec;
typedef struct {
@@ -451,6 +586,10 @@ typedef struct {
modssl_pk_server_t *pks;
modssl_pk_proxy_t *pkp;
+#ifdef HAVE_TLS_SESSION_TICKETS
+ modssl_ticket_key_t *ticket_key;
+#endif
+
ssl_proto_t protocol;
/** config for handling encrypted keys */
@@ -458,13 +597,36 @@ typedef struct {
const char *pphrase_dialog_path;
const char *cert_chain;
+ const char *pkcs7;
/** certificate revocation list */
- const char *crl_path;
- const char *crl_file;
- X509_STORE *crl;
+ const char *crl_path;
+ const char *crl_file;
+ ssl_crlcheck_t crl_check_mode;
+
+#ifdef HAVE_OCSP_STAPLING
+ /** OCSP stapling options */
+ BOOL stapling_enabled;
+ long stapling_resptime_skew;
+ long stapling_resp_maxage;
+ int stapling_cache_timeout;
+ BOOL stapling_return_errors;
+ BOOL stapling_fake_trylater;
+ int stapling_errcache_timeout;
+ apr_interval_time_t stapling_responder_timeout;
+ const char *stapling_force_url;
+#endif
modssl_auth_ctx_t auth;
+
+ BOOL ocsp_enabled; /* true if OCSP verification enabled */
+ BOOL ocsp_force_default; /* true if the default responder URL is
+ * used regardless of per-cert URL */
+ const char *ocsp_responder; /* default responder URL */
+ long ocsp_resptime_skew;
+ long ocsp_resp_maxage;
+ apr_interval_time_t ocsp_responder_timeout;
+
} modssl_ctx_t;
struct SSLSrvConfigRec {
@@ -490,7 +652,7 @@ struct SSLSrvConfigRec {
/**
* Define the mod_ssl per-directory configuration structure
- * (i.e. the local configuration for all <Directory>
+ * (i.e. the local configuration for all &lt;Directory>
* and .htaccess contexts)
*/
typedef struct {
@@ -515,9 +677,6 @@ typedef struct {
/** API glue structures */
extern module AP_MODULE_DECLARE_DATA ssl_module;
-/** "global" stuff */
-extern const char ssl_valid_ssl_mutex_string[];
-
/** configuration handling */
SSLModConfigRec *ssl_config_global_create(server_rec *);
void ssl_config_global_fix(SSLModConfigRec *);
@@ -526,7 +685,6 @@ void *ssl_config_server_create(apr_pool_t *, server_rec *);
void *ssl_config_server_merge(apr_pool_t *, void *, void *);
void *ssl_config_perdir_create(apr_pool_t *, char *);
void *ssl_config_perdir_merge(apr_pool_t *, void *, void *);
-const char *ssl_cmd_SSLMutex(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLPassPhraseDialog(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLCryptoDevice(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLRandomSeed(cmd_parms *, void *, const char *, const char *, const char *);
@@ -535,12 +693,14 @@ const char *ssl_cmd_SSLCipherSuite(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLCertificateFile(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLCertificateKeyFile(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLCertificateChainFile(cmd_parms *, void *, const char *);
+const char *ssl_cmd_SSLPKCS7CertificateFile(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLCACertificatePath(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLCACertificateFile(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLCADNRequestPath(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLCADNRequestFile(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLCARevocationPath(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLCARevocationFile(cmd_parms *, void *, const char *);
+const char *ssl_cmd_SSLCARevocationCheck(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLHonorCipherOrder(cmd_parms *cmd, void *dcfg, int flag);
const char *ssl_cmd_SSLVerifyClient(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLVerifyDepth(cmd_parms *, void *, const char *);
@@ -564,11 +724,23 @@ const char *ssl_cmd_SSLProxyCACertificatePath(cmd_parms *, void *, const char *
const char *ssl_cmd_SSLProxyCACertificateFile(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLProxyCARevocationPath(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLProxyCARevocationFile(cmd_parms *, void *, const char *);
+const char *ssl_cmd_SSLProxyCARevocationCheck(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLProxyMachineCertificatePath(cmd_parms *, void *, const char *);
const char *ssl_cmd_SSLProxyMachineCertificateFile(cmd_parms *, void *, const char *);
+const char *ssl_cmd_SSLProxyMachineCertificateChainFile(cmd_parms *, void *, const char *);
+#ifdef HAVE_TLS_SESSION_TICKETS
+const char *ssl_cmd_SSLSessionTicketKeyFile(cmd_parms *cmd, void *dcfg, const char *arg);
+#endif
const char *ssl_cmd_SSLProxyCheckPeerExpire(cmd_parms *cmd, void *dcfg, int flag);
const char *ssl_cmd_SSLProxyCheckPeerCN(cmd_parms *cmd, void *dcfg, int flag);
+const char *ssl_cmd_SSLOCSPOverrideResponder(cmd_parms *cmd, void *dcfg, int flag);
+const char *ssl_cmd_SSLOCSPDefaultResponder(cmd_parms *cmd, void *dcfg, const char *arg);
+const char *ssl_cmd_SSLOCSPResponseTimeSkew(cmd_parms *cmd, void *dcfg, const char *arg);
+const char *ssl_cmd_SSLOCSPResponseMaxAge(cmd_parms *cmd, void *dcfg, const char *arg);
+const char *ssl_cmd_SSLOCSPResponderTimeout(cmd_parms *cmd, void *dcfg, const char *arg);
+const char *ssl_cmd_SSLOCSPEnable(cmd_parms *cmd, void *dcfg, int flag);
+
const char *ssl_cmd_SSLFIPS(cmd_parms *cmd, void *dcfg, int flag);
/** module initialization */
@@ -576,7 +748,7 @@ int ssl_init_Module(apr_pool_t *, apr_pool_t *, apr_pool_t *, server_re
void ssl_init_Engine(server_rec *, apr_pool_t *);
void ssl_init_ConfigureServer(server_rec *, apr_pool_t *, apr_pool_t *, SSLSrvConfigRec *);
void ssl_init_CheckServers(server_rec *, apr_pool_t *);
-STACK_OF(X509_NAME)
+STACK_OF(X509_NAME)
*ssl_init_FindCAList(server_rec *, apr_pool_t *, const char *, const char *);
void ssl_init_Child(apr_pool_t *, server_rec *);
apr_status_t ssl_init_ModuleKill(void *data);
@@ -590,64 +762,72 @@ int ssl_hook_ReadReq(request_rec *);
int ssl_hook_Upgrade(request_rec *);
void ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s);
+/** Apache authz provisders */
+extern const authz_provider ssl_authz_provider_require_ssl;
+extern const authz_provider ssl_authz_provider_verify_client;
+
/** OpenSSL callbacks */
RSA *ssl_callback_TmpRSA(SSL *, int, int);
DH *ssl_callback_TmpDH(SSL *, int, int);
+#ifndef OPENSSL_NO_EC
+EC_KEY *ssl_callback_TmpECDH(SSL *, int, int);
+#endif
int ssl_callback_SSLVerify(int, X509_STORE_CTX *);
int ssl_callback_SSLVerify_CRL(int, X509_STORE_CTX *, conn_rec *);
-int ssl_callback_proxy_cert(SSL *ssl, MODSSL_CLIENT_CERT_CB_ARG_TYPE **x509, EVP_PKEY **pkey);
+int ssl_callback_proxy_cert(SSL *ssl, X509 **x509, EVP_PKEY **pkey);
int ssl_callback_NewSessionCacheEntry(SSL *, SSL_SESSION *);
SSL_SESSION *ssl_callback_GetSessionCacheEntry(SSL *, unsigned char *, int, int *);
void ssl_callback_DelSessionCacheEntry(SSL_CTX *, SSL_SESSION *);
-void ssl_callback_Info(MODSSL_INFO_CB_ARG_TYPE, int, int);
+void ssl_callback_Info(const SSL *, int, int);
#ifndef OPENSSL_NO_TLSEXT
int ssl_callback_ServerNameIndication(SSL *, int *, modssl_ctx_t *);
#endif
+#ifdef HAVE_TLS_SESSION_TICKETS
+int ssl_callback_SessionTicket(SSL *, unsigned char *, unsigned char *,
+ EVP_CIPHER_CTX *, HMAC_CTX *, int);
+#endif
/** Session Cache Support */
void ssl_scache_init(server_rec *, apr_pool_t *);
void ssl_scache_status_register(apr_pool_t *p);
void ssl_scache_kill(server_rec *);
-BOOL ssl_scache_store(server_rec *, UCHAR *, int, time_t, SSL_SESSION *);
-SSL_SESSION *ssl_scache_retrieve(server_rec *, UCHAR *, int);
-void ssl_scache_remove(server_rec *, UCHAR *, int);
-
-char *ssl_scache_id2sz(UCHAR *, int);
-void ssl_scache_dbm_init(server_rec *, apr_pool_t *);
-void ssl_scache_dbm_kill(server_rec *);
-BOOL ssl_scache_dbm_store(server_rec *, UCHAR *, int, time_t, SSL_SESSION *);
-SSL_SESSION *ssl_scache_dbm_retrieve(server_rec *, UCHAR *, int);
-void ssl_scache_dbm_remove(server_rec *, UCHAR *, int);
-void ssl_scache_dbm_status(request_rec *r, int flags, apr_pool_t *pool);
-
-void ssl_scache_shmcb_init(server_rec *, apr_pool_t *);
-void ssl_scache_shmcb_kill(server_rec *);
-BOOL ssl_scache_shmcb_store(server_rec *, UCHAR *, int, time_t, SSL_SESSION *);
-SSL_SESSION *ssl_scache_shmcb_retrieve(server_rec *, UCHAR *, int);
-void ssl_scache_shmcb_remove(server_rec *, UCHAR *, int);
-void ssl_scache_shmcb_status(request_rec *r, int flags, apr_pool_t *pool);
-
-void ssl_scache_dc_init(server_rec *, apr_pool_t *);
-void ssl_scache_dc_kill(server_rec *);
-BOOL ssl_scache_dc_store(server_rec *, UCHAR *, int, time_t, SSL_SESSION *);
-SSL_SESSION *ssl_scache_dc_retrieve(server_rec *, UCHAR *, int);
-void ssl_scache_dc_remove(server_rec *, UCHAR *, int);
-void ssl_scache_dc_status(request_rec *r, int flags, apr_pool_t *pool);
+BOOL ssl_scache_store(server_rec *, UCHAR *, int,
+ apr_time_t, SSL_SESSION *, apr_pool_t *);
+SSL_SESSION *ssl_scache_retrieve(server_rec *, UCHAR *, int, apr_pool_t *);
+void ssl_scache_remove(server_rec *, UCHAR *, int,
+ apr_pool_t *);
/** Proxy Support */
int ssl_proxy_enable(conn_rec *c);
int ssl_engine_disable(conn_rec *c);
+/** OCSP Stapling Support */
+#ifdef HAVE_OCSP_STAPLING
+const char *ssl_cmd_SSLStaplingCache(cmd_parms *, void *, const char *);
+const char *ssl_cmd_SSLUseStapling(cmd_parms *, void *, int);
+const char *ssl_cmd_SSLStaplingResponseTimeSkew(cmd_parms *, void *, const char *);
+const char *ssl_cmd_SSLStaplingResponseMaxAge(cmd_parms *, void *, const char *);
+const char *ssl_cmd_SSLStaplingStandardCacheTimeout(cmd_parms *, void *, const char *);
+const char *ssl_cmd_SSLStaplingErrorCacheTimeout(cmd_parms *, void *, const char *);
+const char *ssl_cmd_SSLStaplingReturnResponderErrors(cmd_parms *, void *, int);
+const char *ssl_cmd_SSLStaplingFakeTryLater(cmd_parms *, void *, int);
+const char *ssl_cmd_SSLStaplingResponderTimeout(cmd_parms *, void *, const char *);
+const char *ssl_cmd_SSLStaplingForceURL(cmd_parms *, void *, const char *);
+void modssl_init_stapling(server_rec *, apr_pool_t *, apr_pool_t *, modssl_ctx_t *);
+void ssl_stapling_ex_init(void);
+int ssl_stapling_init_cert(server_rec *s, modssl_ctx_t *mctx, X509 *x);
+#endif
+
/** I/O */
-void ssl_io_filter_init(conn_rec *, SSL *);
+void ssl_io_filter_init(conn_rec *, request_rec *r, SSL *);
void ssl_io_filter_register(apr_pool_t *);
-long ssl_io_data_cb(BIO *, int, MODSSL_BIO_CB_ARG_TYPE *, int, long, long);
+long ssl_io_data_cb(BIO *, int, const char *, int, long, long);
/* ssl_io_buffer_fill fills the setaside buffering of the HTTP request
* to allow an SSL renegotiation to take place. */
int ssl_io_buffer_fill(request_rec *r, apr_size_t maxlen);
-/* PRNG */
+/** PRNG */
int ssl_rand_seed(server_rec *, apr_pool_t *, ssl_rsctx_t, char *);
/** Utility Functions */
@@ -658,10 +838,10 @@ void ssl_util_ppclose(server_rec *, apr_pool_t *, apr_file_t *);
char *ssl_util_readfilter(server_rec *, apr_pool_t *, const char *,
const char * const *);
BOOL ssl_util_path_check(ssl_pathcheck_t, const char *, apr_pool_t *);
-ssl_algo_t ssl_util_algotypeof(X509 *, EVP_PKEY *);
+ssl_algo_t ssl_util_algotypeof(X509 *, EVP_PKEY *);
char *ssl_util_algotypestr(ssl_algo_t);
void ssl_util_thread_setup(apr_pool_t *);
-int ssl_init_ssl_connection(conn_rec *c);
+int ssl_init_ssl_connection(conn_rec *c, request_rec *r);
/** Pass Phrase Support */
void ssl_pphrase_Handle(server_rec *, apr_pool_t *);
@@ -685,24 +865,53 @@ const char *ssl_asn1_keystr(int keytype);
const char *ssl_asn1_table_keyfmt(apr_pool_t *p,
const char *id,
int keytype);
+
+STACK_OF(X509) *ssl_read_pkcs7(server_rec *s, const char *pkcs7);
+
/** Mutex Support */
int ssl_mutex_init(server_rec *, apr_pool_t *);
int ssl_mutex_reinit(server_rec *, apr_pool_t *);
int ssl_mutex_on(server_rec *);
int ssl_mutex_off(server_rec *);
+int ssl_stapling_mutex_reinit(server_rec *, apr_pool_t *);
+
+/* mutex type names for Mutex directive */
+#define SSL_CACHE_MUTEX_TYPE "ssl-cache"
+#define SSL_STAPLING_MUTEX_TYPE "ssl-stapling"
+
/** Logfile Support */
void ssl_die(void);
void ssl_log_ssl_error(const char *, int, int, server_rec *);
+/* ssl_log_xerror, ssl_log_cxerror and ssl_log_rxerror are wrappers for the
+ * respective ap_log_*error functions and take a certificate as an
+ * additional argument (whose details are appended to the log message).
+ * The other arguments are interpreted exactly as with their ap_log_*error
+ * counterparts. */
+void ssl_log_xerror(const char *file, int line, int level,
+ apr_status_t rv, apr_pool_t *p, server_rec *s,
+ X509 *cert, const char *format, ...)
+ __attribute__((format(printf,8,9)));
+
+void ssl_log_cxerror(const char *file, int line, int level,
+ apr_status_t rv, conn_rec *c, X509 *cert,
+ const char *format, ...)
+ __attribute__((format(printf,7,8)));
+
+void ssl_log_rxerror(const char *file, int line, int level,
+ apr_status_t rv, request_rec *r, X509 *cert,
+ const char *format, ...)
+ __attribute__((format(printf,7,8)));
+
+#define SSLLOG_MARK __FILE__,__LINE__
+
/** Variables */
/* Register variables for the lifetime of the process pool 'p'. */
void ssl_var_register(apr_pool_t *p);
char *ssl_var_lookup(apr_pool_t *, server_rec *, conn_rec *, request_rec *, char *);
-const char *ssl_ext_lookup(apr_pool_t *p, conn_rec *c, int peer, const char *oid);
-
-extern apr_array_header_t *ssl_extlist_by_oid(request_rec *r, const char *oidstr);
+apr_array_header_t *ssl_ext_list(apr_pool_t *p, conn_rec *c, int peer, const char *extension);
void ssl_var_log_config_register(apr_pool_t *p);
@@ -710,7 +919,22 @@ void ssl_var_log_config_register(apr_pool_t *p);
* allocating from 'p': */
void modssl_var_extract_dns(apr_table_t *t, SSL *ssl, apr_pool_t *p);
-#define APR_SHM_MAXSIZE (64 * 1024 * 1024)
+#ifndef OPENSSL_NO_OCSP
+/* Perform OCSP validation of the current cert in the given context.
+ * Returns non-zero on success or zero on failure. On failure, the
+ * context error code is set. */
+int modssl_verify_ocsp(X509_STORE_CTX *ctx, SSLSrvConfigRec *sc,
+ server_rec *s, conn_rec *c, apr_pool_t *pool);
+
+/* OCSP helper interface; dispatches the given OCSP request to the
+ * responder at the given URI. Returns the decoded OCSP response
+ * object, or NULL on error (in which case, errors will have been
+ * logged). Pool 'p' is used for temporary allocations. */
+OCSP_RESPONSE *modssl_dispatch_ocsp_request(const apr_uri_t *uri,
+ apr_interval_time_t timeout,
+ OCSP_REQUEST *request,
+ conn_rec *c, apr_pool_t *p);
+#endif
#endif /* SSL_PRIVATE_H */
/** @} */
diff --git a/modules/ssl/ssl_scache.c b/modules/ssl/ssl_scache.c
index c85e4f19..2c8d1bc8 100644
--- a/modules/ssl/ssl_scache.c
+++ b/modules/ssl/ssl_scache.c
@@ -40,36 +40,55 @@
void ssl_scache_init(server_rec *s, apr_pool_t *p)
{
SSLModConfigRec *mc = myModConfig(s);
+ apr_status_t rv;
+ struct ap_socache_hints hints;
+
+ /* The very first invocation of this function will be the
+ * post_config invocation during server startup; do nothing for
+ * this first (and only the first) time through, since the pool
+ * will be immediately cleared anyway. For every subsequent
+ * invocation, initialize the configured cache. */
+ if (ap_state_query(AP_SQ_MAIN_STATE) == AP_SQ_MS_CREATE_PRE_CONFIG)
+ return;
+
+#ifdef HAVE_OCSP_STAPLING
+ if (mc->stapling_cache) {
+ memset(&hints, 0, sizeof hints);
+ hints.avg_obj_size = 1500;
+ hints.avg_id_len = 20;
+ hints.expiry_interval = 300;
+
+ rv = mc->stapling_cache->init(mc->stapling_cache_context,
+ "mod_ssl-stapling", &hints, s, p);
+ if (rv) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01872)
+ "Could not initialize stapling cache. Exiting.");
+ ssl_die();
+ }
+ }
+#endif
/*
* Warn the user that he should use the session cache.
* But we can operate without it, of course.
*/
- if (mc->nSessionCacheMode == SSL_SCMODE_UNSET) {
- ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
+ if (mc->sesscache == NULL) {
+ ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s, APLOGNO(01873)
"Init: Session Cache is not configured "
"[hint: SSLSessionCache]");
- mc->nSessionCacheMode = SSL_SCMODE_NONE;
return;
}
- if (mc->nSessionCacheMode == SSL_SCMODE_DBM)
- ssl_scache_dbm_init(s, p);
-#ifdef HAVE_DISTCACHE
- else if (mc->nSessionCacheMode == SSL_SCMODE_DC)
- ssl_scache_dc_init(s, p);
-#endif
- else if (mc->nSessionCacheMode == SSL_SCMODE_SHMCB) {
- void *data;
- const char *userdata_key = "ssl_scache_init";
-
- apr_pool_userdata_get(&data, userdata_key, s->process->pool);
- if (!data) {
- apr_pool_userdata_set((const void *)1, userdata_key,
- apr_pool_cleanup_null, s->process->pool);
- return;
- }
- ssl_scache_shmcb_init(s, p);
+ memset(&hints, 0, sizeof hints);
+ hints.avg_obj_size = 150;
+ hints.avg_id_len = 30;
+ hints.expiry_interval = 30;
+
+ rv = mc->sesscache->init(mc->sesscache_context, "mod_ssl-session", &hints, s, p);
+ if (rv) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01874)
+ "Could not initialize session cache. Exiting.");
+ ssl_die();
}
}
@@ -77,62 +96,95 @@ void ssl_scache_kill(server_rec *s)
{
SSLModConfigRec *mc = myModConfig(s);
- if (mc->nSessionCacheMode == SSL_SCMODE_DBM)
- ssl_scache_dbm_kill(s);
- else if (mc->nSessionCacheMode == SSL_SCMODE_SHMCB)
- ssl_scache_shmcb_kill(s);
-#ifdef HAVE_DISTCACHE
- else if (mc->nSessionCacheMode == SSL_SCMODE_DC)
- ssl_scache_dc_kill(s);
+ if (mc->sesscache) {
+ mc->sesscache->destroy(mc->sesscache_context, s);
+ }
+
+#ifdef HAVE_OCSP_STAPLING
+ if (mc->stapling_cache) {
+ mc->stapling_cache->destroy(mc->stapling_cache_context, s);
+ }
#endif
- return;
+
}
-BOOL ssl_scache_store(server_rec *s, UCHAR *id, int idlen, time_t expiry, SSL_SESSION *sess)
+BOOL ssl_scache_store(server_rec *s, UCHAR *id, int idlen,
+ apr_time_t expiry, SSL_SESSION *sess,
+ apr_pool_t *p)
{
SSLModConfigRec *mc = myModConfig(s);
- BOOL rv = FALSE;
-
- if (mc->nSessionCacheMode == SSL_SCMODE_DBM)
- rv = ssl_scache_dbm_store(s, id, idlen, expiry, sess);
- else if (mc->nSessionCacheMode == SSL_SCMODE_SHMCB)
- rv = ssl_scache_shmcb_store(s, id, idlen, expiry, sess);
-#ifdef HAVE_DISTCACHE
- else if (mc->nSessionCacheMode == SSL_SCMODE_DC)
- rv = ssl_scache_dc_store(s, id, idlen, expiry, sess);
-#endif
- return rv;
+ unsigned char encoded[SSL_SESSION_MAX_DER], *ptr;
+ unsigned int len;
+ apr_status_t rv;
+
+ /* Serialise the session. */
+ len = i2d_SSL_SESSION(sess, NULL);
+ if (len > sizeof encoded) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01875)
+ "session is too big (%u bytes)", len);
+ return FALSE;
+ }
+
+ ptr = encoded;
+ len = i2d_SSL_SESSION(sess, &ptr);
+
+ if (mc->sesscache->flags & AP_SOCACHE_FLAG_NOTMPSAFE) {
+ ssl_mutex_on(s);
+ }
+
+ rv = mc->sesscache->store(mc->sesscache_context, s, id, idlen,
+ expiry, encoded, len, p);
+
+ if (mc->sesscache->flags & AP_SOCACHE_FLAG_NOTMPSAFE) {
+ ssl_mutex_off(s);
+ }
+
+ return rv == APR_SUCCESS ? TRUE : FALSE;
}
-SSL_SESSION *ssl_scache_retrieve(server_rec *s, UCHAR *id, int idlen)
+SSL_SESSION *ssl_scache_retrieve(server_rec *s, UCHAR *id, int idlen,
+ apr_pool_t *p)
{
SSLModConfigRec *mc = myModConfig(s);
- SSL_SESSION *sess = NULL;
-
- if (mc->nSessionCacheMode == SSL_SCMODE_DBM)
- sess = ssl_scache_dbm_retrieve(s, id, idlen);
- else if (mc->nSessionCacheMode == SSL_SCMODE_SHMCB)
- sess = ssl_scache_shmcb_retrieve(s, id, idlen);
-#ifdef HAVE_DISTCACHE
- else if (mc->nSessionCacheMode == SSL_SCMODE_DC)
- sess = ssl_scache_dc_retrieve(s, id, idlen);
-#endif
- return sess;
+ unsigned char dest[SSL_SESSION_MAX_DER];
+ unsigned int destlen = SSL_SESSION_MAX_DER;
+ MODSSL_D2I_SSL_SESSION_CONST unsigned char *ptr;
+ apr_status_t rv;
+
+ if (mc->sesscache->flags & AP_SOCACHE_FLAG_NOTMPSAFE) {
+ ssl_mutex_on(s);
+ }
+
+ rv = mc->sesscache->retrieve(mc->sesscache_context, s, id, idlen,
+ dest, &destlen, p);
+
+ if (mc->sesscache->flags & AP_SOCACHE_FLAG_NOTMPSAFE) {
+ ssl_mutex_off(s);
+ }
+
+ if (rv != APR_SUCCESS) {
+ return NULL;
+ }
+
+ ptr = dest;
+
+ return d2i_SSL_SESSION(NULL, &ptr, destlen);
}
-void ssl_scache_remove(server_rec *s, UCHAR *id, int idlen)
+void ssl_scache_remove(server_rec *s, UCHAR *id, int idlen,
+ apr_pool_t *p)
{
SSLModConfigRec *mc = myModConfig(s);
- if (mc->nSessionCacheMode == SSL_SCMODE_DBM)
- ssl_scache_dbm_remove(s, id, idlen);
- else if (mc->nSessionCacheMode == SSL_SCMODE_SHMCB)
- ssl_scache_shmcb_remove(s, id, idlen);
-#ifdef HAVE_DISTCACHE
- else if (mc->nSessionCacheMode == SSL_SCMODE_DC)
- ssl_scache_dc_remove(s, id, idlen);
-#endif
- return;
+ if (mc->sesscache->flags & AP_SOCACHE_FLAG_NOTMPSAFE) {
+ ssl_mutex_on(s);
+ }
+
+ mc->sesscache->remove(mc->sesscache_context, s, id, idlen, p);
+
+ if (mc->sesscache->flags & AP_SOCACHE_FLAG_NOTMPSAFE) {
+ ssl_mutex_off(s);
+ }
}
/* _________________________________________________________________
@@ -142,9 +194,9 @@ void ssl_scache_remove(server_rec *s, UCHAR *id, int idlen)
*/
static int ssl_ext_status_hook(request_rec *r, int flags)
{
- SSLSrvConfigRec *sc = mySrvConfig(r->server);
+ SSLModConfigRec *mc = myModConfig(r->server);
- if (sc == NULL || flags & AP_STATUS_SHORT)
+ if (mc == NULL || flags & AP_STATUS_SHORT || mc->sesscache == NULL)
return OK;
ap_rputs("<hr>\n", r);
@@ -154,14 +206,15 @@ static int ssl_ext_status_hook(request_rec *r, int flags)
ap_rputs("</td></tr>\n", r);
ap_rputs("<tr><td bgcolor=\"#ffffff\">\n", r);
- if (sc->mc->nSessionCacheMode == SSL_SCMODE_DBM)
- ssl_scache_dbm_status(r, flags, r->pool);
- else if (sc->mc->nSessionCacheMode == SSL_SCMODE_SHMCB)
- ssl_scache_shmcb_status(r, flags, r->pool);
-#ifdef HAVE_DISTCACHE
- else if (sc->mc->nSessionCacheMode == SSL_SCMODE_DC)
- ssl_scache_dc_status(r, flags, r->pool);
-#endif
+ if (mc->sesscache->flags & AP_SOCACHE_FLAG_NOTMPSAFE) {
+ ssl_mutex_on(r->server);
+ }
+
+ mc->sesscache->status(mc->sesscache_context, r, flags);
+
+ if (mc->sesscache->flags & AP_SOCACHE_FLAG_NOTMPSAFE) {
+ ssl_mutex_off(r->server);
+ }
ap_rputs("</td></tr>\n", r);
ap_rputs("</table>\n", r);
diff --git a/modules/ssl/ssl_scache_dbm.c b/modules/ssl/ssl_scache_dbm.c
deleted file mode 100644
index cdcce9d8..00000000
--- a/modules/ssl/ssl_scache_dbm.c
+++ /dev/null
@@ -1,464 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* _ _
- * _ __ ___ ___ __| | ___ ___| | mod_ssl
- * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL
- * | | | | | | (_) | (_| | \__ \__ \ |
- * |_| |_| |_|\___/ \__,_|___|___/___/_|
- * |_____|
- * ssl_scache_dbm.c
- * Session Cache via DBM
- */
-
-#include "ssl_private.h"
-
-static void ssl_scache_dbm_expire(server_rec *s);
-
-void ssl_scache_dbm_init(server_rec *s, apr_pool_t *p)
-{
- SSLModConfigRec *mc = myModConfig(s);
- apr_dbm_t *dbm;
- apr_status_t rv;
-
- /* for the DBM we need the data file */
- if (mc->szSessionCacheDataFile == NULL) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
- "SSLSessionCache required");
- ssl_die();
- }
-
- /* open it once to create it and to make sure it _can_ be created */
- ssl_mutex_on(s);
- if ((rv = apr_dbm_open(&dbm, mc->szSessionCacheDataFile,
- APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, mc->pPool)) != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
- "Cannot create SSLSessionCache DBM file `%s'",
- mc->szSessionCacheDataFile);
- ssl_mutex_off(s);
- return;
- }
- apr_dbm_close(dbm);
-
-#if !defined(OS2) && !defined(WIN32) && !defined(BEOS) && !defined(NETWARE)
- /*
- * We have to make sure the Apache child processes have access to
- * the DBM file. But because there are brain-dead platforms where we
- * cannot exactly determine the suffixes we try all possibilities.
- */
- if (geteuid() == 0 /* is superuser */) {
- chown(mc->szSessionCacheDataFile, unixd_config.user_id, -1 /* no gid change */);
- if (chown(apr_pstrcat(p, mc->szSessionCacheDataFile, SSL_DBM_FILE_SUFFIX_DIR, NULL),
- unixd_config.user_id, -1) == -1) {
- if (chown(apr_pstrcat(p, mc->szSessionCacheDataFile, ".db", NULL),
- unixd_config.user_id, -1) == -1)
- chown(apr_pstrcat(p, mc->szSessionCacheDataFile, ".dir", NULL),
- unixd_config.user_id, -1);
- }
- if (chown(apr_pstrcat(p, mc->szSessionCacheDataFile, SSL_DBM_FILE_SUFFIX_PAG, NULL),
- unixd_config.user_id, -1) == -1) {
- if (chown(apr_pstrcat(p, mc->szSessionCacheDataFile, ".db", NULL),
- unixd_config.user_id, -1) == -1)
- chown(apr_pstrcat(p, mc->szSessionCacheDataFile, ".pag", NULL),
- unixd_config.user_id, -1);
- }
- }
-#endif
- ssl_mutex_off(s);
- ssl_scache_dbm_expire(s);
- return;
-}
-
-void ssl_scache_dbm_kill(server_rec *s)
-{
- SSLModConfigRec *mc = myModConfig(s);
- apr_pool_t *p;
-
- apr_pool_create_ex(&p, mc->pPool, NULL, NULL);
- if (p != NULL) {
- /* the correct way */
- unlink(apr_pstrcat(p, mc->szSessionCacheDataFile, SSL_DBM_FILE_SUFFIX_DIR, NULL));
- unlink(apr_pstrcat(p, mc->szSessionCacheDataFile, SSL_DBM_FILE_SUFFIX_PAG, NULL));
- /* the additional ways to be sure */
- unlink(apr_pstrcat(p, mc->szSessionCacheDataFile, ".dir", NULL));
- unlink(apr_pstrcat(p, mc->szSessionCacheDataFile, ".pag", NULL));
- unlink(apr_pstrcat(p, mc->szSessionCacheDataFile, ".db", NULL));
- unlink(mc->szSessionCacheDataFile);
- apr_pool_destroy(p);
- }
- return;
-}
-
-BOOL ssl_scache_dbm_store(server_rec *s, UCHAR *id, int idlen, time_t expiry, SSL_SESSION *sess)
-{
- SSLModConfigRec *mc = myModConfig(s);
- apr_dbm_t *dbm;
- apr_datum_t dbmkey;
- apr_datum_t dbmval;
- UCHAR ucaData[SSL_SESSION_MAX_DER];
- int nData;
- UCHAR *ucp;
- apr_status_t rv;
-
- /* streamline session data */
- if ((nData = i2d_SSL_SESSION(sess, NULL)) > sizeof(ucaData)) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "streamline session data size too large: %d > "
- "%" APR_SIZE_T_FMT,
- nData, sizeof(ucaData));
- return FALSE;
- }
- ucp = ucaData;
- i2d_SSL_SESSION(sess, &ucp);
-
- /* be careful: do not try to store too much bytes in a DBM file! */
-#ifdef PAIRMAX
- if ((idlen + nData) >= PAIRMAX) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "data size too large for DBM session cache: %d >= %d",
- (idlen + nData), PAIRMAX);
- return FALSE;
- }
-#else
- if ((idlen + nData) >= 950 /* at least less than approx. 1KB */) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "data size too large for DBM session cache: %d >= %d",
- (idlen + nData), 950);
- return FALSE;
- }
-#endif
-
- /* create DBM key */
- dbmkey.dptr = (char *)id;
- dbmkey.dsize = idlen;
-
- /* create DBM value */
- dbmval.dsize = sizeof(time_t) + nData;
- dbmval.dptr = (char *)malloc(dbmval.dsize);
- if (dbmval.dptr == NULL) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "malloc error creating DBM value");
- return FALSE;
- }
- memcpy((char *)dbmval.dptr, &expiry, sizeof(time_t));
- memcpy((char *)dbmval.dptr+sizeof(time_t), ucaData, nData);
-
- /* and store it to the DBM file */
- ssl_mutex_on(s);
- if ((rv = apr_dbm_open(&dbm, mc->szSessionCacheDataFile,
- APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, mc->pPool)) != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
- "Cannot open SSLSessionCache DBM file `%s' for writing "
- "(store)",
- mc->szSessionCacheDataFile);
- ssl_mutex_off(s);
- free(dbmval.dptr);
- return FALSE;
- }
- if ((rv = apr_dbm_store(dbm, dbmkey, dbmval)) != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
- "Cannot store SSL session to DBM file `%s'",
- mc->szSessionCacheDataFile);
- apr_dbm_close(dbm);
- ssl_mutex_off(s);
- free(dbmval.dptr);
- return FALSE;
- }
- apr_dbm_close(dbm);
- ssl_mutex_off(s);
-
- /* free temporary buffers */
- free(dbmval.dptr);
-
- /* allow the regular expiring to occur */
- ssl_scache_dbm_expire(s);
-
- return TRUE;
-}
-
-SSL_SESSION *ssl_scache_dbm_retrieve(server_rec *s, UCHAR *id, int idlen)
-{
- SSLModConfigRec *mc = myModConfig(s);
- apr_dbm_t *dbm;
- apr_datum_t dbmkey;
- apr_datum_t dbmval;
- SSL_SESSION *sess = NULL;
- MODSSL_D2I_SSL_SESSION_CONST unsigned char *ucpData;
- int nData;
- time_t expiry;
- time_t now;
- apr_status_t rc;
-
- /* allow the regular expiring to occur */
- ssl_scache_dbm_expire(s);
-
- /* create DBM key and values */
- dbmkey.dptr = (char *)id;
- dbmkey.dsize = idlen;
-
- /* and fetch it from the DBM file
- * XXX: Should we open the dbm against r->pool so the cleanup will
- * do the apr_dbm_close? This would make the code a bit cleaner.
- */
- ssl_mutex_on(s);
- if ((rc = apr_dbm_open(&dbm, mc->szSessionCacheDataFile,
- APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, mc->pPool)) != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_ERR, rc, s,
- "Cannot open SSLSessionCache DBM file `%s' for reading "
- "(fetch)",
- mc->szSessionCacheDataFile);
- ssl_mutex_off(s);
- return NULL;
- }
- rc = apr_dbm_fetch(dbm, dbmkey, &dbmval);
- if (rc != APR_SUCCESS) {
- apr_dbm_close(dbm);
- ssl_mutex_off(s);
- return NULL;
- }
- if (dbmval.dptr == NULL || dbmval.dsize <= sizeof(time_t)) {
- apr_dbm_close(dbm);
- ssl_mutex_off(s);
- return NULL;
- }
-
- /* parse resulting data */
- nData = dbmval.dsize-sizeof(time_t);
- ucpData = malloc(nData);
- if (ucpData == NULL) {
- apr_dbm_close(dbm);
- ssl_mutex_off(s);
- return NULL;
- }
- /* Cast needed, ucpData may be const */
- memcpy((unsigned char *)ucpData,
- (char *)dbmval.dptr + sizeof(time_t), nData);
- memcpy(&expiry, dbmval.dptr, sizeof(time_t));
-
- apr_dbm_close(dbm);
- ssl_mutex_off(s);
-
- /* make sure the stuff is still not expired */
- now = time(NULL);
- if (expiry <= now) {
- ssl_scache_dbm_remove(s, id, idlen);
- return NULL;
- }
-
- /* unstreamed SSL_SESSION */
- sess = d2i_SSL_SESSION(NULL, &ucpData, nData);
-
- return sess;
-}
-
-void ssl_scache_dbm_remove(server_rec *s, UCHAR *id, int idlen)
-{
- SSLModConfigRec *mc = myModConfig(s);
- apr_dbm_t *dbm;
- apr_datum_t dbmkey;
- apr_status_t rv;
-
- /* create DBM key and values */
- dbmkey.dptr = (char *)id;
- dbmkey.dsize = idlen;
-
- /* and delete it from the DBM file */
- ssl_mutex_on(s);
- if ((rv = apr_dbm_open(&dbm, mc->szSessionCacheDataFile,
- APR_DBM_RWCREATE, SSL_DBM_FILE_MODE, mc->pPool)) != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
- "Cannot open SSLSessionCache DBM file `%s' for writing "
- "(delete)",
- mc->szSessionCacheDataFile);
- ssl_mutex_off(s);
- return;
- }
- apr_dbm_delete(dbm, dbmkey);
- apr_dbm_close(dbm);
- ssl_mutex_off(s);
-
- return;
-}
-
-static void ssl_scache_dbm_expire(server_rec *s)
-{
- SSLModConfigRec *mc = myModConfig(s);
- SSLSrvConfigRec *sc = mySrvConfig(s);
- static time_t tLast = 0;
- apr_dbm_t *dbm;
- apr_datum_t dbmkey;
- apr_datum_t dbmval;
- apr_pool_t *p;
- time_t tExpiresAt;
- int nElements = 0;
- int nDeleted = 0;
- int bDelete;
- apr_datum_t *keylist;
- int keyidx;
- int i;
- time_t tNow;
- apr_status_t rv;
-
- /*
- * make sure the expiration for still not-accessed session
- * cache entries is done only from time to time
- */
- tNow = time(NULL);
- if (tNow < tLast+sc->session_cache_timeout)
- return;
- tLast = tNow;
-
- /*
- * Here we have to be very carefully: Not all DBM libraries are
- * smart enough to allow one to iterate over the elements and at the
- * same time delete expired ones. Some of them get totally crazy
- * while others have no problems. So we have to do it the slower but
- * more safe way: we first iterate over all elements and remember
- * those which have to be expired. Then in a second pass we delete
- * all those expired elements. Additionally we reopen the DBM file
- * to be really safe in state.
- */
-
-#define KEYMAX 1024
-
- ssl_mutex_on(s);
- for (;;) {
- /* allocate the key array in a memory sub pool */
- apr_pool_create_ex(&p, mc->pPool, NULL, NULL);
- if (p == NULL)
- break;
- if ((keylist = apr_palloc(p, sizeof(dbmkey)*KEYMAX)) == NULL) {
- apr_pool_destroy(p);
- break;
- }
-
- /* pass 1: scan DBM database */
- keyidx = 0;
- if ((rv = apr_dbm_open(&dbm, mc->szSessionCacheDataFile,
- APR_DBM_RWCREATE,SSL_DBM_FILE_MODE,
- p)) != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
- "Cannot open SSLSessionCache DBM file `%s' for "
- "scanning",
- mc->szSessionCacheDataFile);
- apr_pool_destroy(p);
- break;
- }
- apr_dbm_firstkey(dbm, &dbmkey);
- while (dbmkey.dptr != NULL) {
- nElements++;
- bDelete = FALSE;
- apr_dbm_fetch(dbm, dbmkey, &dbmval);
- if (dbmval.dsize <= sizeof(time_t) || dbmval.dptr == NULL)
- bDelete = TRUE;
- else {
- memcpy(&tExpiresAt, dbmval.dptr, sizeof(time_t));
- if (tExpiresAt <= tNow)
- bDelete = TRUE;
- }
- if (bDelete) {
- if ((keylist[keyidx].dptr = apr_pmemdup(p, dbmkey.dptr, dbmkey.dsize)) != NULL) {
- keylist[keyidx].dsize = dbmkey.dsize;
- keyidx++;
- if (keyidx == KEYMAX)
- break;
- }
- }
- apr_dbm_nextkey(dbm, &dbmkey);
- }
- apr_dbm_close(dbm);
-
- /* pass 2: delete expired elements */
- if (apr_dbm_open(&dbm, mc->szSessionCacheDataFile,
- APR_DBM_RWCREATE,SSL_DBM_FILE_MODE, p) != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
- "Cannot re-open SSLSessionCache DBM file `%s' for "
- "expiring",
- mc->szSessionCacheDataFile);
- apr_pool_destroy(p);
- break;
- }
- for (i = 0; i < keyidx; i++) {
- apr_dbm_delete(dbm, keylist[i]);
- nDeleted++;
- }
- apr_dbm_close(dbm);
-
- /* destroy temporary pool */
- apr_pool_destroy(p);
-
- if (keyidx < KEYMAX)
- break;
- }
- ssl_mutex_off(s);
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "Inter-Process Session Cache (DBM) Expiry: "
- "old: %d, new: %d, removed: %d",
- nElements, nElements-nDeleted, nDeleted);
- return;
-}
-
-void ssl_scache_dbm_status(request_rec *r, int flags, apr_pool_t *p)
-{
- SSLModConfigRec *mc = myModConfig(r->server);
- apr_dbm_t *dbm;
- apr_datum_t dbmkey;
- apr_datum_t dbmval;
- int nElem;
- int nSize;
- int nAverage;
- apr_status_t rv;
-
- nElem = 0;
- nSize = 0;
- ssl_mutex_on(r->server);
- /*
- * XXX - Check what pool is to be used - TBD
- */
- if ((rv = apr_dbm_open(&dbm, mc->szSessionCacheDataFile,
- APR_DBM_RWCREATE, SSL_DBM_FILE_MODE,
- mc->pPool)) != APR_SUCCESS) {
- ap_log_rerror(APLOG_MARK, APLOG_ERR, rv, r,
- "Cannot open SSLSessionCache DBM file `%s' for status "
- "retrival",
- mc->szSessionCacheDataFile);
- ssl_mutex_off(r->server);
- return;
- }
- /*
- * XXX - Check the return value of apr_dbm_firstkey, apr_dbm_fetch - TBD
- */
- apr_dbm_firstkey(dbm, &dbmkey);
- for ( ; dbmkey.dptr != NULL; apr_dbm_nextkey(dbm, &dbmkey)) {
- apr_dbm_fetch(dbm, dbmkey, &dbmval);
- if (dbmval.dptr == NULL)
- continue;
- nElem += 1;
- nSize += dbmval.dsize;
- }
- apr_dbm_close(dbm);
- ssl_mutex_off(r->server);
- if (nSize > 0 && nElem > 0)
- nAverage = nSize / nElem;
- else
- nAverage = 0;
- ap_rprintf(r, "cache type: <b>DBM</b>, maximum size: <b>unlimited</b><br>");
- ap_rprintf(r, "current sessions: <b>%d</b>, current size: <b>%d</b> bytes<br>", nElem, nSize);
- ap_rprintf(r, "average session size: <b>%d</b> bytes<br>", nAverage);
- return;
-}
-
diff --git a/modules/ssl/ssl_scache_dc.c b/modules/ssl/ssl_scache_dc.c
deleted file mode 100644
index b03b0dea..00000000
--- a/modules/ssl/ssl_scache_dc.c
+++ /dev/null
@@ -1,177 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* _ _
- * _ __ ___ ___ __| | ___ ___| | mod_ssl
- * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL
- * | | | | | | (_) | (_| | \__ \__ \ |
- * |_| |_| |_|\___/ \__,_|___|___/___/_|
- * |_____|
- * ssl_scache_dc.c
- * Distributed Session Cache (client support)
- */
-
-#include "ssl_private.h"
-
-/* Only build this code if it's enabled at configure-time. */
-#ifdef HAVE_DISTCACHE
-
-#include "distcache/dc_client.h"
-
-#if !defined(DISTCACHE_CLIENT_API) || (DISTCACHE_CLIENT_API < 0x0001)
-#error "You must compile with a more recent version of the distcache-base package"
-#endif
-
-/*
- * This cache implementation allows modssl to access 'distcache' servers (or
- * proxies) to facilitate distributed session caching. It is based on code
- * released as open source by Cryptographic Appliances Inc, and was developed by
- * Geoff Thorpe, Steve Robb, and Chris Zimmerman.
- */
-
-/*
-**
-** High-Level "handlers" as per ssl_scache.c
-**
-*/
-
-void ssl_scache_dc_init(server_rec *s, apr_pool_t *p)
-{
- DC_CTX *ctx;
- SSLModConfigRec *mc = myModConfig(s);
- /*
- * Create a session context
- */
- if (mc->szSessionCacheDataFile == NULL) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "SSLSessionCache required");
- ssl_die();
- }
-#if 0
- /* If a "persistent connection" mode of operation is preferred, you *must*
- * also use the PIDCHECK flag to ensure fork()'d processes don't interlace
- * comms on the same connection as each other. */
-#define SESSION_CTX_FLAGS SESSION_CTX_FLAG_PERSISTENT | \
- SESSION_CTX_FLAG_PERSISTENT_PIDCHECK | \
- SESSION_CTX_FLAG_PERSISTENT_RETRY | \
- SESSION_CTX_FLAG_PERSISTENT_LATE
-#else
- /* This mode of operation will open a temporary connection to the 'target'
- * for each cache operation - this makes it safe against fork()
- * automatically. This mode is preferred when running a local proxy (over
- * unix domain sockets) because overhead is negligable and it reduces the
- * performance/stability danger of file-descriptor bloatage. */
-#define SESSION_CTX_FLAGS 0
-#endif
- ctx = DC_CTX_new(mc->szSessionCacheDataFile, SESSION_CTX_FLAGS);
- if (!ctx) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache failed to obtain context");
- ssl_die();
- }
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, "distributed scache context initialised");
- /*
- * Success ...
- */
- mc->tSessionCacheDataTable = ctx;
- return;
-}
-
-void ssl_scache_dc_kill(server_rec *s)
-{
- SSLModConfigRec *mc = myModConfig(s);
-
- if (mc->tSessionCacheDataTable)
- DC_CTX_free(mc->tSessionCacheDataTable);
- mc->tSessionCacheDataTable = NULL;
-}
-
-BOOL ssl_scache_dc_store(server_rec *s, UCHAR *id, int idlen,
- time_t timeout, SSL_SESSION * pSession)
-{
- unsigned char der[SSL_SESSION_MAX_DER];
- int der_len;
- unsigned char *pder = der;
- SSLModConfigRec *mc = myModConfig(s);
- DC_CTX *ctx = mc->tSessionCacheDataTable;
-
- /* Serialise the SSL_SESSION object */
- if ((der_len = i2d_SSL_SESSION(pSession, NULL)) > SSL_SESSION_MAX_DER)
- return FALSE;
- i2d_SSL_SESSION(pSession, &pder);
- /* !@#$%^ - why do we deal with *absolute* time anyway??? */
- timeout -= time(NULL);
- /* Send the serialised session to the distributed cache context */
- if (!DC_CTX_add_session(ctx, id, idlen, der, der_len,
- (unsigned long)timeout * 1000)) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache 'add_session' failed");
- return FALSE;
- }
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "distributed scache 'add_session' successful");
- return TRUE;
-}
-
-SSL_SESSION *ssl_scache_dc_retrieve(server_rec *s, UCHAR *id, int idlen)
-{
- unsigned char der[SSL_SESSION_MAX_DER];
- unsigned int der_len;
- SSL_SESSION *pSession;
- MODSSL_D2I_SSL_SESSION_CONST unsigned char *pder = der;
- SSLModConfigRec *mc = myModConfig(s);
- DC_CTX *ctx = mc->tSessionCacheDataTable;
-
- /* Retrieve any corresponding session from the distributed cache context */
- if (!DC_CTX_get_session(ctx, id, idlen, der, SSL_SESSION_MAX_DER,
- &der_len)) {
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "distributed scache 'get_session' MISS");
- return NULL;
- }
- if (der_len > SSL_SESSION_MAX_DER) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache 'get_session' OVERFLOW");
- return NULL;
- }
- pSession = d2i_SSL_SESSION(NULL, &pder, der_len);
- if (!pSession) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache 'get_session' CORRUPT");
- return NULL;
- }
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "distributed scache 'get_session' HIT");
- return pSession;
-}
-
-void ssl_scache_dc_remove(server_rec *s, UCHAR *id, int idlen)
-{
- SSLModConfigRec *mc = myModConfig(s);
- DC_CTX *ctx = mc->tSessionCacheDataTable;
-
- /* Remove any corresponding session from the distributed cache context */
- if (!DC_CTX_remove_session(ctx, id, idlen)) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache 'remove_session' MISS");
- } else {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "distributed scache 'remove_session' HIT");
- }
-}
-
-void ssl_scache_dc_status(request_rec *r, int flags, apr_pool_t *pool)
-{
- SSLModConfigRec *mc = myModConfig(r->server);
-
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
- "distributed scache 'ssl_scache_dc_status'");
- ap_rprintf(r, "cache type: <b>DC (Distributed Cache)</b>, "
- " target: <b>%s</b><br>", mc->szSessionCacheDataFile);
-}
-
-#endif
-
diff --git a/modules/ssl/ssl_scache_shmcb.c b/modules/ssl/ssl_scache_shmcb.c
deleted file mode 100644
index e778db04..00000000
--- a/modules/ssl/ssl_scache_shmcb.c
+++ /dev/null
@@ -1,769 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* _ _
- * _ __ ___ ___ __| | ___ ___| | mod_ssl
- * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL
- * | | | | | | (_) | (_| | \__ \__ \ |
- * |_| |_| |_|\___/ \__,_|___|___/___/_|
- * |_____|
- * ssl_scache_shmcb.c
- * Session Cache via Shared Memory (Cyclic Buffer Variant)
- */
-
-#include "ssl_private.h"
-
-/*
- * This shared memory based SSL session cache implementation was
- * originally written by Geoff Thorpe <geoff geoffthorpe.net> for C2Net
- * Europe as a contribution to Ralf Engelschall's mod_ssl project.
- *
- * Since rewritten by GT to not use alignment-fudging memcpys and reduce
- * complexity.
- */
-
-/*
- * Header structure - the start of the shared-mem segment
- */
-typedef struct {
- /* Stats for cache operations */
- unsigned long stat_stores;
- unsigned long stat_expiries;
- unsigned long stat_scrolled;
- unsigned long stat_retrieves_hit;
- unsigned long stat_retrieves_miss;
- unsigned long stat_removes_hit;
- unsigned long stat_removes_miss;
- /* Number of subcaches */
- unsigned int subcache_num;
- /* How many indexes each subcache's queue has */
- unsigned int index_num;
- /* How large each subcache is, including the queue and data */
- unsigned int subcache_size;
- /* How far into each subcache the data area is (optimisation) */
- unsigned int subcache_data_offset;
- /* How large the data area in each subcache is (optimisation) */
- unsigned int subcache_data_size;
-} SHMCBHeader;
-
-/*
- * Subcache structure - the start of each subcache, followed by
- * indexes then data
- */
-typedef struct {
- /* The start position and length of the cyclic buffer of indexes */
- unsigned int idx_pos, idx_used;
- /* Same for the data area */
- unsigned int data_pos, data_used;
-} SHMCBSubcache;
-
-/*
- * Index structure - each subcache has an array of these
- */
-typedef struct {
- /* absolute time this entry expires */
- time_t expires;
- /* location within the subcache's data area */
- unsigned int data_pos;
- /* size (most logic ignores this, we keep it only to minimise memcpy) */
- unsigned int data_used;
- /* Optimisation to prevent ASN decoding unless a match is likely */
- unsigned char s_id2;
- /* Used to mark explicitly-removed sessions */
- unsigned char removed;
-} SHMCBIndex;
-
-
-/* The SHM data segment is of fixed size and stores data as follows.
- *
- * [ SHMCBHeader | Subcaches ]
- *
- * The SHMCBHeader header structure stores metadata concerning the
- * cache and the contained subcaches.
- *
- * Subcaches is a hash table of header->subcache_num SHMCBSubcache
- * structures. The hash table is indexed by SHMCB_MASK(id). Each
- * SHMCBSubcache structure has a fixed size (header->subcache_size),
- * which is determined at creation time, and looks like the following:
- *
- * [ SHMCBSubcache | Indexes | Data ]
- *
- * Each subcache is prefixed by the SHMCBSubcache structure.
- *
- * The subcache's "Data" segment is a single cyclic data buffer, of
- * total size header->subcache_data_size; data inside is referenced
- * using byte offsets. The offset marking the beginning of the cyclic
- * buffer is subcache->data_pos the buffer's length is
- * subcache->data_used.
- *
- * "Indexes" is an array of header->index_num SHMCBIndex structures,
- * which is used as a cyclic queue; subcache->idx_pos gives the array
- * index of the first in use, subcache->idx_used gives the number in
- * use. Both ->idx_* values have a range of [0, header->index_num)
- *
- * Each in-use SHMCBIndex structure represents a single SSL session.
- */
-
-/* This macro takes a pointer to the header and a zero-based index and returns
- * a pointer to the corresponding subcache. */
-#define SHMCB_SUBCACHE(pHeader, num) \
- (SHMCBSubcache *)(((unsigned char *)(pHeader)) + \
- sizeof(SHMCBHeader) + \
- (num) * ((pHeader)->subcache_size))
-
-/* This macro takes a pointer to the header and a session id and returns a
- * pointer to the corresponding subcache. */
-#define SHMCB_MASK(pHeader, id) \
- SHMCB_SUBCACHE((pHeader), *(id) & ((pHeader)->subcache_num - 1))
-
-/* This macro takes the same params as the last, generating two outputs for use
- * in ap_log_error(...). */
-#define SHMCB_MASK_DBG(pHeader, id) \
- *(id), (*(id) & ((pHeader)->subcache_num - 1))
-
-/* This macro takes a pointer to a subcache and a zero-based index and returns
- * a pointer to the corresponding SHMCBIndex. */
-#define SHMCB_INDEX(pSubcache, num) \
- ((SHMCBIndex *)(((unsigned char *)pSubcache) + \
- sizeof(SHMCBSubcache)) + num)
-
-/* This macro takes a pointer to the header and a subcache and returns a
- * pointer to the corresponding data area. */
-#define SHMCB_DATA(pHeader, pSubcache) \
- ((unsigned char *)(pSubcache) + (pHeader)->subcache_data_offset)
-
-/*
- * Cyclic functions - assists in "wrap-around"/modulo logic
- */
-
-/* Addition modulo 'mod' */
-#define SHMCB_CYCLIC_INCREMENT(val,inc,mod) \
- (((val) + (inc)) % (mod))
-
-/* Subtraction (or "distance between") modulo 'mod' */
-#define SHMCB_CYCLIC_SPACE(val1,val2,mod) \
- ((val2) >= (val1) ? ((val2) - (val1)) : \
- ((val2) + (mod) - (val1)))
-
-/* A "normal-to-cyclic" memcpy. */
-static void shmcb_cyclic_ntoc_memcpy(unsigned int buf_size, unsigned char *data,
- unsigned int dest_offset, unsigned char *src,
- unsigned int src_len)
-{
- if (dest_offset + src_len < buf_size)
- /* It be copied all in one go */
- memcpy(data + dest_offset, src, src_len);
- else {
- /* Copy the two splits */
- memcpy(data + dest_offset, src, buf_size - dest_offset);
- memcpy(data, src + buf_size - dest_offset,
- src_len + dest_offset - buf_size);
- }
-}
-
-/* A "cyclic-to-normal" memcpy. */
-static void shmcb_cyclic_cton_memcpy(unsigned int buf_size, unsigned char *dest,
- unsigned char *data, unsigned int src_offset,
- unsigned int src_len)
-{
- if (src_offset + src_len < buf_size)
- /* It be copied all in one go */
- memcpy(dest, data + src_offset, src_len);
- else {
- /* Copy the two splits */
- memcpy(dest, data + src_offset, buf_size - src_offset);
- memcpy(dest + buf_size - src_offset, data,
- src_len + src_offset - buf_size);
- }
-}
-
-/* Prototypes for low-level subcache operations */
-static void shmcb_subcache_expire(server_rec *, SHMCBHeader *, SHMCBSubcache *);
-static BOOL shmcb_subcache_store(server_rec *, SHMCBHeader *, SHMCBSubcache *,
- UCHAR *, unsigned int, UCHAR *, time_t);
-static SSL_SESSION *shmcb_subcache_retrieve(server_rec *, SHMCBHeader *, SHMCBSubcache *,
- UCHAR *, unsigned int);
-static BOOL shmcb_subcache_remove(server_rec *, SHMCBHeader *, SHMCBSubcache *,
- UCHAR *, unsigned int);
-
-/*
- * High-Level "handlers" as per ssl_scache.c
- * subcache internals are deferred to shmcb_subcache_*** functions lower down
- */
-
-void ssl_scache_shmcb_init(server_rec *s, apr_pool_t *p)
-{
- SSLModConfigRec *mc = myModConfig(s);
- void *shm_segment;
- apr_size_t shm_segsize;
- apr_status_t rv;
- SHMCBHeader *header;
- unsigned int num_subcache, num_idx, loop;
-
- /* Create shared memory segment */
- if (mc->szSessionCacheDataFile == NULL) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
- "SSLSessionCache required");
- ssl_die();
- }
-
- /* Use anonymous shm by default, fall back on name-based. */
- rv = apr_shm_create(&(mc->pSessionCacheDataMM),
- mc->nSessionCacheDataSize,
- NULL, mc->pPool);
- if (APR_STATUS_IS_ENOTIMPL(rv)) {
- /* For a name-based segment, remove it first in case of a
- * previous unclean shutdown. */
- apr_shm_remove(mc->szSessionCacheDataFile, mc->pPool);
-
- rv = apr_shm_create(&(mc->pSessionCacheDataMM),
- mc->nSessionCacheDataSize,
- mc->szSessionCacheDataFile,
- mc->pPool);
- }
-
- if (rv != APR_SUCCESS) {
- ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
- "could not allocate shared memory for shmcb "
- "session cache");
- ssl_die();
- }
-
- shm_segment = apr_shm_baseaddr_get(mc->pSessionCacheDataMM);
- shm_segsize = apr_shm_size_get(mc->pSessionCacheDataMM);
- if (shm_segsize < (5 * sizeof(SHMCBHeader))) {
- /* the segment is ridiculously small, bail out */
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
- "shared memory segment too small");
- ssl_die();
- }
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "shmcb_init allocated %" APR_SIZE_T_FMT
- " bytes of shared memory",
- shm_segsize);
- /* Discount the header */
- shm_segsize -= sizeof(SHMCBHeader);
- /* Select the number of subcaches to create and how many indexes each
- * should contain based on the size of the memory (the header has already
- * been subtracted). Typical non-client-auth sslv3/tlsv1 sessions are
- * around 150 bytes, so erring to division by 120 helps ensure we would
- * exhaust data storage before index storage (except sslv2, where it's
- * *slightly* the other way). From there, we select the number of subcaches
- * to be a power of two, such that the number of indexes per subcache at
- * least twice the number of subcaches. */
- num_idx = (shm_segsize) / 120;
- num_subcache = 256;
- while ((num_idx / num_subcache) < (2 * num_subcache))
- num_subcache /= 2;
- num_idx /= num_subcache;
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "for %" APR_SIZE_T_FMT " bytes (%" APR_SIZE_T_FMT
- " including header), recommending %u subcaches, "
- "%u indexes each", shm_segsize,
- shm_segsize + sizeof(SHMCBHeader), num_subcache, num_idx);
- if (num_idx < 5) {
- /* we're still too small, bail out */
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
- "shared memory segment too small");
- ssl_die();
- }
- /* OK, we're sorted */
- header = shm_segment;
- header->stat_stores = 0;
- header->stat_expiries = 0;
- header->stat_scrolled = 0;
- header->stat_retrieves_hit = 0;
- header->stat_retrieves_miss = 0;
- header->stat_removes_hit = 0;
- header->stat_removes_miss = 0;
- header->subcache_num = num_subcache;
- /* Convert the subcache size (in bytes) to a value that is suitable for
- * structure alignment on the host platform, by rounding down if necessary.
- * This assumes that sizeof(unsigned long) provides an appropriate
- * alignment unit. */
- header->subcache_size = ((size_t)(shm_segsize / num_subcache) &
- ~(size_t)(sizeof(unsigned long) - 1));
- header->subcache_data_offset = sizeof(SHMCBSubcache) +
- num_idx * sizeof(SHMCBIndex);
- header->subcache_data_size = header->subcache_size -
- header->subcache_data_offset;
- header->index_num = num_idx;
-
- /* Output trace info */
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "shmcb_init_memory choices follow");
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "subcache_num = %u", header->subcache_num);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "subcache_size = %u", header->subcache_size);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "subcache_data_offset = %u", header->subcache_data_offset);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "subcache_data_size = %u", header->subcache_data_size);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "index_num = %u", header->index_num);
- /* The header is done, make the caches empty */
- for (loop = 0; loop < header->subcache_num; loop++) {
- SHMCBSubcache *subcache = SHMCB_SUBCACHE(header, loop);
- subcache->idx_pos = subcache->idx_used = 0;
- subcache->data_pos = subcache->data_used = 0;
- }
- ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
- "Shared memory session cache initialised");
- /* Success ... */
- mc->tSessionCacheDataTable = shm_segment;
-}
-
-void ssl_scache_shmcb_kill(server_rec *s)
-{
- SSLModConfigRec *mc = myModConfig(s);
-
- if (mc->pSessionCacheDataMM != NULL) {
- apr_shm_destroy(mc->pSessionCacheDataMM);
- mc->pSessionCacheDataMM = NULL;
- }
- return;
-}
-
-BOOL ssl_scache_shmcb_store(server_rec *s, UCHAR *id, int idlen,
- time_t timeout, SSL_SESSION * pSession)
-{
- SSLModConfigRec *mc = myModConfig(s);
- BOOL to_return = FALSE;
- unsigned char encoded[SSL_SESSION_MAX_DER];
- unsigned char *ptr_encoded;
- unsigned int len_encoded;
- SHMCBHeader *header = mc->tSessionCacheDataTable;
- SHMCBSubcache *subcache = SHMCB_MASK(header, id);
-
- ssl_mutex_on(s);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "ssl_scache_shmcb_store (0x%02x -> subcache %d)",
- SHMCB_MASK_DBG(header, id));
- if (idlen < 4) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "unusably short session_id provided "
- "(%u bytes)", idlen);
- goto done;
- }
- /* Serialise the session. */
- len_encoded = i2d_SSL_SESSION(pSession, NULL);
- if (len_encoded > SSL_SESSION_MAX_DER) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
- "session is too big (%u bytes)", len_encoded);
- goto done;
- }
- ptr_encoded = encoded;
- len_encoded = i2d_SSL_SESSION(pSession, &ptr_encoded);
- if (!shmcb_subcache_store(s, header, subcache, encoded,
- len_encoded, id, timeout)) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
- "can't store a session!");
- goto done;
- }
- header->stat_stores++;
- to_return = TRUE;
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "leaving ssl_scache_shmcb_store successfully");
-done:
- ssl_mutex_off(s);
- return to_return;
-}
-
-SSL_SESSION *ssl_scache_shmcb_retrieve(server_rec *s, UCHAR *id, int idlen)
-{
- SSLModConfigRec *mc = myModConfig(s);
- SSL_SESSION *pSession = NULL;
- SHMCBHeader *header = mc->tSessionCacheDataTable;
- SHMCBSubcache *subcache = SHMCB_MASK(header, id);
-
- ssl_mutex_on(s);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "ssl_scache_shmcb_retrieve (0x%02x -> subcache %d)",
- SHMCB_MASK_DBG(header, id));
- if (idlen < 4) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "unusably short session_id provided "
- "(%u bytes)", idlen);
- goto done;
- }
- /* Get the session corresponding to the session_id or NULL if it doesn't
- * exist (or is flagged as "removed"). */
- pSession = shmcb_subcache_retrieve(s, header, subcache, id, idlen);
- if (pSession)
- header->stat_retrieves_hit++;
- else
- header->stat_retrieves_miss++;
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "leaving ssl_scache_shmcb_retrieve successfully");
-done:
- ssl_mutex_off(s);
- return pSession;
-}
-
-void ssl_scache_shmcb_remove(server_rec *s, UCHAR *id, int idlen)
-{
- SSLModConfigRec *mc = myModConfig(s);
- SHMCBHeader *header = mc->tSessionCacheDataTable;
- SHMCBSubcache *subcache = SHMCB_MASK(header, id);
-
- ssl_mutex_on(s);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "ssl_scache_shmcb_remove (0x%02x -> subcache %d)",
- SHMCB_MASK_DBG(header, id));
- if (idlen < 4) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "unusably short session_id provided "
- "(%u bytes)", idlen);
- goto done;
- }
- if (shmcb_subcache_remove(s, header, subcache, id, idlen))
- header->stat_removes_hit++;
- else
- header->stat_removes_miss++;
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "leaving ssl_scache_shmcb_remove successfully");
-done:
- ssl_mutex_off(s);
-}
-
-void ssl_scache_shmcb_status(request_rec *r, int flags, apr_pool_t *p)
-{
- server_rec *s = r->server;
- SSLModConfigRec *mc = myModConfig(s);
- void *shm_segment = apr_shm_baseaddr_get(mc->pSessionCacheDataMM);
- SHMCBHeader *header = shm_segment;
- unsigned int loop, total = 0, cache_total = 0, non_empty_subcaches = 0;
- time_t idx_expiry, min_expiry = 0, max_expiry = 0, average_expiry = 0;
- time_t now = time(NULL);
- double expiry_total = 0;
- int index_pct, cache_pct;
-
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "inside shmcb_status");
- /* Perform the iteration inside the mutex to avoid corruption or invalid
- * pointer arithmetic. The rest of our logic uses read-only header data so
- * doesn't need the lock. */
- ssl_mutex_on(s);
- /* Iterate over the subcaches */
- for (loop = 0; loop < header->subcache_num; loop++) {
- SHMCBSubcache *subcache = SHMCB_SUBCACHE(header, loop);
- shmcb_subcache_expire(s, header, subcache);
- total += subcache->idx_used;
- cache_total += subcache->data_used;
- if (subcache->idx_used) {
- SHMCBIndex *idx = SHMCB_INDEX(subcache, subcache->idx_pos);
- non_empty_subcaches++;
- idx_expiry = idx->expires;
- expiry_total += (double)idx_expiry;
- max_expiry = ((idx_expiry > max_expiry) ? idx_expiry : max_expiry);
- if (!min_expiry)
- min_expiry = idx_expiry;
- else
- min_expiry = ((idx_expiry < min_expiry) ? idx_expiry : min_expiry);
- }
- }
- ssl_mutex_off(s);
- index_pct = (100 * total) / (header->index_num *
- header->subcache_num);
- cache_pct = (100 * cache_total) / (header->subcache_data_size *
- header->subcache_num);
- /* Generate HTML */
- ap_rprintf(r, "cache type: <b>SHMCB</b>, shared memory: <b>%d</b> "
- "bytes, current sessions: <b>%d</b><br>",
- mc->nSessionCacheDataSize, total);
- ap_rprintf(r, "subcaches: <b>%d</b>, indexes per subcache: <b>%d</b><br>",
- header->subcache_num, header->index_num);
- if (non_empty_subcaches) {
- average_expiry = (time_t)(expiry_total / (double)non_empty_subcaches);
- ap_rprintf(r, "time left on oldest entries' SSL sessions: ");
- if (now < average_expiry)
- ap_rprintf(r, "avg: <b>%d</b> seconds, (range: %d...%d)<br>",
- (int)(average_expiry - now),
- (int)(min_expiry - now),
- (int)(max_expiry - now));
- else
- ap_rprintf(r, "expiry_threshold: <b>Calculation error!</b><br>");
- }
-
- ap_rprintf(r, "index usage: <b>%d%%</b>, cache usage: <b>%d%%</b><br>",
- index_pct, cache_pct);
- ap_rprintf(r, "total sessions stored since starting: <b>%lu</b><br>",
- header->stat_stores);
- ap_rprintf(r, "total sessions expired since starting: <b>%lu</b><br>",
- header->stat_expiries);
- ap_rprintf(r, "total (pre-expiry) sessions scrolled out of the cache: "
- "<b>%lu</b><br>", header->stat_scrolled);
- ap_rprintf(r, "total retrieves since starting: <b>%lu</b> hit, "
- "<b>%lu</b> miss<br>", header->stat_retrieves_hit,
- header->stat_retrieves_miss);
- ap_rprintf(r, "total removes since starting: <b>%lu</b> hit, "
- "<b>%lu</b> miss<br>", header->stat_removes_hit,
- header->stat_removes_miss);
- ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, "leaving shmcb_status");
-}
-
-/*
- * Subcache-level cache operations
- */
-
-static void shmcb_subcache_expire(server_rec *s, SHMCBHeader *header,
- SHMCBSubcache *subcache)
-{
- time_t now = time(NULL);
- unsigned int loop = 0;
- unsigned int new_idx_pos = subcache->idx_pos;
- SHMCBIndex *idx = NULL;
-
- while (loop < subcache->idx_used) {
- idx = SHMCB_INDEX(subcache, new_idx_pos);
- if (idx->expires > now)
- /* it hasn't expired yet, we're done iterating */
- break;
- loop++;
- new_idx_pos = SHMCB_CYCLIC_INCREMENT(new_idx_pos, 1, header->index_num);
- }
- if (!loop)
- /* Nothing to do */
- return;
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "will be expiring %u sessions", loop);
- if (loop == subcache->idx_used) {
- /* We're expiring everything, piece of cake */
- subcache->idx_used = 0;
- subcache->data_used = 0;
- } else {
- /* There remain other indexes, so we can use idx to adjust 'data' */
- unsigned int diff = SHMCB_CYCLIC_SPACE(subcache->data_pos,
- idx->data_pos,
- header->subcache_data_size);
- /* Adjust the indexes */
- subcache->idx_used -= loop;
- subcache->idx_pos = new_idx_pos;
- /* Adjust the data area */
- subcache->data_used -= diff;
- subcache->data_pos = idx->data_pos;
- }
- header->stat_expiries += loop;
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "we now have %u sessions", subcache->idx_used);
-}
-
-static BOOL shmcb_subcache_store(server_rec *s, SHMCBHeader *header,
- SHMCBSubcache *subcache,
- UCHAR *data, unsigned int data_len,
- UCHAR *id, time_t expiry)
-{
- unsigned int new_offset, new_idx;
- SHMCBIndex *idx;
-
- /* Sanity check the input */
- if ((data_len > header->subcache_data_size) || (data_len > SSL_SESSION_MAX_DER)) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
- "inserting session larger (%d) than subcache data area (%d)",
- data_len, header->subcache_data_size);
- return FALSE;
- }
-
- /* If there are entries to expire, ditch them first. */
- shmcb_subcache_expire(s, header, subcache);
-
- /* Loop until there is enough space to insert */
- if (header->subcache_data_size - subcache->data_used < data_len
- || subcache->idx_used == header->index_num) {
- unsigned int loop = 0;
-
- idx = SHMCB_INDEX(subcache, subcache->idx_pos);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "about to force-expire, subcache: idx_used=%d, "
- "data_used=%d", subcache->idx_used, subcache->data_used);
- do {
- SHMCBIndex *idx2;
-
- /* Adjust the indexes by one */
- subcache->idx_pos = SHMCB_CYCLIC_INCREMENT(subcache->idx_pos, 1,
- header->index_num);
- subcache->idx_used--;
- if (!subcache->idx_used) {
- /* There's nothing left */
- subcache->data_used = 0;
- break;
- }
- /* Adjust the data */
- idx2 = SHMCB_INDEX(subcache, subcache->idx_pos);
- subcache->data_used -= SHMCB_CYCLIC_SPACE(idx->data_pos, idx2->data_pos,
- header->subcache_data_size);
- subcache->data_pos = idx2->data_pos;
- /* Stats */
- header->stat_scrolled++;
- /* Loop admin */
- idx = idx2;
- loop++;
- } while (header->subcache_data_size - subcache->data_used < data_len);
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "finished force-expire, subcache: idx_used=%d, "
- "data_used=%d", subcache->idx_used, subcache->data_used);
- }
-
- /* HERE WE ASSUME THAT THE NEW SESSION SHOULD GO ON THE END! I'M NOT
- * CHECKING WHETHER IT SHOULD BE GENUINELY "INSERTED" SOMEWHERE.
- *
- * We either fix that, or find out at a "higher" (read "mod_ssl")
- * level whether it is possible to have distinct session caches for
- * any attempted tomfoolery to do with different session timeouts.
- * Knowing in advance that we can have a cache-wide constant timeout
- * would make this stuff *MUCH* more efficient. Mind you, it's very
- * efficient right now because I'm ignoring this problem!!!
- */
- /* Insert the data */
- new_offset = SHMCB_CYCLIC_INCREMENT(subcache->data_pos, subcache->data_used,
- header->subcache_data_size);
- shmcb_cyclic_ntoc_memcpy(header->subcache_data_size,
- SHMCB_DATA(header, subcache), new_offset,
- data, data_len);
- subcache->data_used += data_len;
- /* Insert the index */
- new_idx = SHMCB_CYCLIC_INCREMENT(subcache->idx_pos, subcache->idx_used,
- header->index_num);
- idx = SHMCB_INDEX(subcache, new_idx);
- idx->expires = expiry;
- idx->data_pos = new_offset;
- idx->data_used = data_len;
- idx->s_id2 = id[1];
- idx->removed = 0;
- subcache->idx_used++;
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "insert happened at idx=%d, data=%d", new_idx, new_offset);
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "finished insert, subcache: idx_pos/idx_used=%d/%d, "
- "data_pos/data_used=%d/%d",
- subcache->idx_pos, subcache->idx_used,
- subcache->data_pos, subcache->data_used);
- return TRUE;
-}
-
-static SSL_SESSION *shmcb_subcache_retrieve(server_rec *s, SHMCBHeader *header,
- SHMCBSubcache *subcache, UCHAR *id,
- unsigned int idlen)
-{
- unsigned int pos;
- unsigned int loop = 0;
-
- /* If there are entries to expire, ditch them first. */
- shmcb_subcache_expire(s, header, subcache);
- pos = subcache->idx_pos;
-
- while (loop < subcache->idx_used) {
- SHMCBIndex *idx = SHMCB_INDEX(subcache, pos);
-
- /* Only consider 'idx' if;
- * (a) the s_id2 byte matches
- * (b) the "removed" flag isn't set.
- */
- if ((idx->s_id2 == id[1]) && !idx->removed) {
- SSL_SESSION *pSession;
- unsigned char *s_id;
- unsigned int s_idlen;
- unsigned char tempasn[SSL_SESSION_MAX_DER];
- MODSSL_D2I_SSL_SESSION_CONST unsigned char *ptr = tempasn;
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "possible match at idx=%d, data=%d", pos, idx->data_pos);
- /* Copy the data */
- shmcb_cyclic_cton_memcpy(header->subcache_data_size,
- tempasn, SHMCB_DATA(header, subcache),
- idx->data_pos, idx->data_used);
- /* Decode the session */
- pSession = d2i_SSL_SESSION(NULL, &ptr, idx->data_used);
- if (!pSession) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
- "shmcb_subcache_retrieve internal error");
- return NULL;
- }
- s_id = SSL_SESSION_get_session_id(pSession);
- s_idlen = SSL_SESSION_get_session_id_length(pSession);
- if (s_idlen == idlen && memcmp(s_id, id, idlen) == 0) {
- /* Found the matching session */
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "shmcb_subcache_retrieve returning matching session");
- return pSession;
- }
- SSL_SESSION_free(pSession);
- }
- /* Increment */
- loop++;
- pos = SHMCB_CYCLIC_INCREMENT(pos, 1, header->index_num);
- }
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "shmcb_subcache_retrieve found no match");
- return NULL;
-}
-
-static BOOL shmcb_subcache_remove(server_rec *s, SHMCBHeader *header,
- SHMCBSubcache *subcache,
- UCHAR *id, unsigned int idlen)
-{
- unsigned int pos;
- unsigned int loop = 0;
- BOOL to_return = FALSE;
-
- /* Unlike the others, we don't do an expire-run first. This is to keep
- * consistent statistics where a "remove" operation may actually be the
- * higher layer spotting an expiry issue prior to us. Our caller is
- * handling stats, so a failure return would be inconsistent if the
- * intended session was in fact removed by an expiry run. */
-
- pos = subcache->idx_pos;
- while (!to_return && (loop < subcache->idx_used)) {
- SHMCBIndex *idx = SHMCB_INDEX(subcache, pos);
- /* Only consider 'idx' if the s_id2 byte matches and it's not already
- * removed - easiest way to avoid costly ASN decodings. */
- if ((idx->s_id2 == id[1]) && !idx->removed) {
- SSL_SESSION *pSession;
- unsigned char *s_id;
- unsigned int s_idlen;
- unsigned char tempasn[SSL_SESSION_MAX_DER];
- MODSSL_D2I_SSL_SESSION_CONST unsigned char *ptr = tempasn;
-
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "possible match at idx=%d, data=%d", pos, idx->data_pos);
- /* Copy the data */
- shmcb_cyclic_cton_memcpy(header->subcache_data_size,
- tempasn, SHMCB_DATA(header, subcache),
- idx->data_pos, idx->data_used);
- /* Decode the session */
- pSession = d2i_SSL_SESSION(NULL, &ptr, idx->data_used);
- if (!pSession) {
- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
- "shmcb_subcache_remove internal error");
- return FALSE;
- }
- s_id = SSL_SESSION_get_session_id(pSession);
- s_idlen = SSL_SESSION_get_session_id_length(pSession);
- if (s_idlen == idlen && memcmp(s_id, id, idlen) == 0) {
- /* Found the matching session, remove it quietly. */
- idx->removed = 1;
- to_return = TRUE;
- ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
- "shmcb_subcache_remove removing matching session");
- }
- SSL_SESSION_free(pSession);
- }
- /* Increment */
- loop++;
- pos = SHMCB_CYCLIC_INCREMENT(pos, 1, header->index_num);
- }
-
- return to_return;
-}
diff --git a/modules/ssl/ssl_toolkit_compat.h b/modules/ssl/ssl_toolkit_compat.h
deleted file mode 100644
index 369516b2..00000000
--- a/modules/ssl/ssl_toolkit_compat.h
+++ /dev/null
@@ -1,281 +0,0 @@
-/* Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef SSL_TOOLKIT_COMPAT_H
-#define SSL_TOOLKIT_COMPAT_H
-
-/**
- * @file ssl_toolkit_compat.h
- * @brief this header file provides a compatiblity layer
- * between OpenSSL and RSA sslc
- *
- * @defgroup MOD_SSL_TOOLKIT Toolkit
- * @ingroup MOD_SSL
- * @{
- */
-
-#ifdef HAVE_OPENSSL
-
-/** OpenSSL headers */
-#include <openssl/ssl.h>
-#include <openssl/err.h>
-#include <openssl/x509.h>
-#include <openssl/pem.h>
-#include <openssl/crypto.h>
-#include <openssl/evp.h>
-#include <openssl/rand.h>
-#include <openssl/x509v3.h>
-/** Avoid tripping over an engine build installed globally and detected
- * when the user points at an explicit non-engine flavor of OpenSSL
- */
-#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
-#include <openssl/engine.h>
-#endif
-
-/**
- * rsa sslc uses incomplete types for most structures
- * so we macroize for OpenSSL those which cannot be dereferenced
- * using the same sames as the sslc functions
- */
-
-#define EVP_PKEY_key_type(k) (EVP_PKEY_type(k->type))
-
-#define X509_NAME_get_entries(xs) (xs->entries)
-#define X509_REVOKED_get_serialNumber(xs) (xs->serialNumber)
-
-#define X509_get_signature_algorithm(xs) (xs->cert_info->signature->algorithm)
-#define X509_get_key_algorithm(xs) (xs->cert_info->key->algor->algorithm)
-
-#define X509_NAME_ENTRY_get_data_ptr(xs) (xs->value->data)
-#define X509_NAME_ENTRY_get_data_len(xs) (xs->value->length)
-
-#define SSL_CTX_get_extra_certs(ctx) (ctx->extra_certs)
-#define SSL_CTX_set_extra_certs(ctx,value) {ctx->extra_certs = value;}
-
-#define SSL_CIPHER_get_name(s) (s->name)
-#define SSL_CIPHER_get_valid(s) (s->valid)
-
-#define SSL_SESSION_get_session_id(s) (s->session_id)
-#define SSL_SESSION_get_session_id_length(s) (s->session_id_length)
-
-/**
- * Support for retrieving/overriding states
- */
-#ifndef SSL_get_state
-#define SSL_get_state(ssl) SSL_state(ssl)
-#endif
-
-#define SSL_set_state(ssl,val) (ssl)->state = val
-
-#define MODSSL_BIO_CB_ARG_TYPE const char
-#define MODSSL_CRYPTO_CB_ARG_TYPE const char
-#if (OPENSSL_VERSION_NUMBER < 0x00907000)
-# define MODSSL_INFO_CB_ARG_TYPE SSL*
-#else
-# define MODSSL_INFO_CB_ARG_TYPE const SSL*
-#endif
-#define MODSSL_CLIENT_CERT_CB_ARG_TYPE X509
-#define MODSSL_PCHAR_CAST
-
-/** ...shifting sands of openssl... */
-#if (OPENSSL_VERSION_NUMBER >= 0x0090707f)
-# define MODSSL_D2I_SSL_SESSION_CONST const
-# define MODSSL_SSL_CIPHER_CONST const
-#else
-# define MODSSL_D2I_SSL_SESSION_CONST
-# define MODSSL_SSL_CIPHER_CONST
-#endif
-
-#if (OPENSSL_VERSION_NUMBER >= 0x00908000)
-# define MODSSL_D2I_PrivateKey_CONST const
-# define MODSSL_D2I_X509_CONST const
-#else
-# define MODSSL_D2I_PrivateKey_CONST
-# define MODSSL_D2I_X509_CONST
-#endif
-
-#if (OPENSSL_VERSION_NUMBER >= 0x00909000)
-# define MODSSL_SSL_METHOD_CONST const
-#else
-# define MODSSL_SSL_METHOD_CONST
-#endif
-
-#define modssl_X509_verify_cert X509_verify_cert
-
-typedef int (modssl_read_bio_cb_fn)(char*,int,int,void*);
-
-#if (OPENSSL_VERSION_NUMBER < 0x00904000)
-#define modssl_PEM_read_bio_X509(b, x, cb, arg) PEM_read_bio_X509(b, x, cb)
-#else
-#define modssl_PEM_read_bio_X509(b, x, cb, arg) PEM_read_bio_X509(b, x, cb, arg)
-#endif
-
-#define modssl_PEM_X509_INFO_read_bio PEM_X509_INFO_read_bio
-
-#define modssl_PEM_read_bio_PrivateKey PEM_read_bio_PrivateKey
-
-#define modssl_set_cipher_list SSL_set_cipher_list
-
-#define modssl_free OPENSSL_free
-
-#define EVP_PKEY_reference_inc(pkey) \
- CRYPTO_add(&((pkey)->references), +1, CRYPTO_LOCK_X509_PKEY)
-
-#define X509_reference_inc(cert) \
- CRYPTO_add(&((cert)->references), +1, CRYPTO_LOCK_X509)
-
-#define HAVE_SSL_RAND_EGD /* since 9.5.1 */
-
-#define HAVE_SSL_X509V3_EXT_d2i
-
-#if (OPENSSL_VERSION_NUMBER >= 0x009080a0) && defined(OPENSSL_FIPS)
-#define HAVE_FIPS
-#endif
-
-#ifndef PEM_F_DEF_CALLBACK
-#ifdef PEM_F_PEM_DEF_CALLBACK
-/** In OpenSSL 0.9.8 PEM_F_DEF_CALLBACK was renamed */
-#define PEM_F_DEF_CALLBACK PEM_F_PEM_DEF_CALLBACK
-#endif
-#endif
-
-#elif defined(HAVE_SSLC)
-
-#include <bio.h>
-#include <ssl.h>
-#include <err.h>
-#include <x509.h>
-#include <pem.h>
-#include <evp.h>
-#include <objects.h>
-#include <sslc.h>
-
-/** sslc does not support this function, OpenSSL has since 9.5.1 */
-#define RAND_status() 1
-
-/** sslc names this function a bit differently */
-#define CRYPTO_num_locks() CRYPTO_get_num_locks()
-
-#ifndef STACK_OF
-#define STACK_OF(type) STACK
-#endif
-
-#define MODSSL_BIO_CB_ARG_TYPE char
-#define MODSSL_CRYPTO_CB_ARG_TYPE char
-#define MODSSL_INFO_CB_ARG_TYPE SSL*
-#define MODSSL_CLIENT_CERT_CB_ARG_TYPE void
-#define MODSSL_PCHAR_CAST (char *)
-#define MODSSL_D2I_SSL_SESSION_CONST
-#define MODSSL_D2I_PrivateKey_CONST
-#define MODSSL_D2I_X509_CONST
-
-typedef int (modssl_read_bio_cb_fn)(char*,int,int);
-
-#define modssl_X509_verify_cert(c) X509_verify_cert(c, NULL)
-
-#define modssl_PEM_read_bio_X509(b, x, cb, arg) \
- PEM_read_bio_X509(b, x, cb)
-
-#define modssl_PEM_X509_INFO_read_bio(b, x, cb, arg)\
- PEM_X509_INFO_read_bio(b, x, cb)
-
-#define modssl_PEM_read_bio_PrivateKey(b, k, cb, arg) \
- PEM_read_bio_PrivateKey(b, k, cb)
-
-#ifndef HAVE_SSL_SET_STATE
-#define SSL_set_state(ssl, state) /** XXX: should throw an error */
-#endif
-
-#define modssl_set_cipher_list(ssl, l) \
- SSL_set_cipher_list(ssl, (char *)l)
-
-#define modssl_free free
-
-#ifndef PEM_F_DEF_CALLBACK
-#define PEM_F_DEF_CALLBACK PEM_F_DEF_CB
-#endif
-
-#if SSLC_VERSION_NUMBER < 0x2000
-
-#define X509_STORE_CTX_set_depth(st, d)
-#define X509_CRL_get_lastUpdate(x) ((x)->crl->lastUpdate)
-#define X509_CRL_get_nextUpdate(x) ((x)->crl->nextUpdate)
-#define X509_CRL_get_REVOKED(x) ((x)->crl->revoked)
-#define X509_REVOKED_get_serialNumber(xs) (xs->serialNumber)
-
-#define modssl_set_verify(ssl, verify, cb) \
- SSL_set_verify(ssl, verify)
-
-#else /** SSLC_VERSION_NUMBER >= 0x2000 */
-
-#define CRYPTO_malloc_init R_malloc_init
-
-#define EVP_cleanup()
-
-#endif /** SSLC_VERSION_NUMBER >= 0x2000 */
-
-typedef void (*modssl_popfree_fn)(char *data);
-
-#define sk_SSL_CIPHER_dup sk_dup
-#define sk_SSL_CIPHER_find(st, data) sk_find(st, (void *)data)
-#define sk_SSL_CIPHER_free sk_free
-#define sk_SSL_CIPHER_num sk_num
-#define sk_SSL_CIPHER_value (SSL_CIPHER *)sk_value
-#define sk_X509_num sk_num
-#define sk_X509_push sk_push
-#define sk_X509_pop_free(st, free) sk_pop_free((STACK*)(st), (modssl_popfree_fn)(free))
-#define sk_X509_value (X509 *)sk_value
-#define sk_X509_INFO_free sk_free
-#define sk_X509_INFO_pop_free(st, free) sk_pop_free((STACK*)(st), (modssl_popfree_fn)(free))
-#define sk_X509_INFO_num sk_num
-#define sk_X509_INFO_new_null sk_new_null
-#define sk_X509_INFO_value (X509_INFO *)sk_value
-#define sk_X509_NAME_find(st, data) sk_find(st, (void *)data)
-#define sk_X509_NAME_free sk_free
-#define sk_X509_NAME_new sk_new
-#define sk_X509_NAME_num sk_num
-#define sk_X509_NAME_push(st, data) sk_push(st, (void *)data)
-#define sk_X509_NAME_value (X509_NAME *)sk_value
-#define sk_X509_NAME_ENTRY_num sk_num
-#define sk_X509_NAME_ENTRY_value (X509_NAME_ENTRY *)sk_value
-#define sk_X509_NAME_set_cmp_func sk_set_cmp_func
-#define sk_X509_REVOKED_num sk_num
-#define sk_X509_REVOKED_value (X509_REVOKED *)sk_value
-
-#else /** ! HAVE_OPENSSL && ! HAVE_SSLC */
-
-#error "Unrecognized SSL Toolkit!"
-
-#endif /* ! HAVE_OPENSSL && ! HAVE_SSLC */
-
-#ifndef modssl_set_verify
-#define modssl_set_verify(ssl, verify, cb) \
- SSL_set_verify(ssl, verify, cb)
-#endif
-
-#ifndef SSL_SESS_CACHE_NO_INTERNAL
-#define SSL_SESS_CACHE_NO_INTERNAL SSL_SESS_CACHE_NO_INTERNAL_LOOKUP
-#endif
-
-#ifndef OPENSSL_NO_TLSEXT
-#ifndef SSL_CTRL_SET_TLSEXT_HOSTNAME
-#define OPENSSL_NO_TLSEXT
-#endif
-#endif
-
-#endif /* SSL_TOOLKIT_COMPAT_H */
-
-/** @} */
diff --git a/modules/ssl/ssl_util.c b/modules/ssl/ssl_util.c
index e4387e61..6b5a7de6 100644
--- a/modules/ssl/ssl_util.c
+++ b/modules/ssl/ssl_util.c
@@ -125,6 +125,8 @@ BOOL ssl_util_path_check(ssl_pathcheck_t pcm, const char *path, apr_pool_t *p)
if (pcm & SSL_PCM_EXISTS && apr_stat(&finfo, path,
APR_FINFO_TYPE|APR_FINFO_SIZE, p) != 0)
return FALSE;
+ AP_DEBUG_ASSERT((pcm & SSL_PCM_EXISTS) ||
+ !(pcm & (SSL_PCM_ISREG|SSL_PCM_ISDIR|SSL_PCM_ISNONZERO)));
if (pcm & SSL_PCM_ISREG && finfo.filetype != APR_REG)
return FALSE;
if (pcm & SSL_PCM_ISDIR && finfo.filetype != APR_DIR)
@@ -143,22 +145,24 @@ ssl_algo_t ssl_util_algotypeof(X509 *pCert, EVP_PKEY *pKey)
if (pCert != NULL)
pFreeKey = pKey = X509_get_pubkey(pCert);
if (pKey != NULL) {
- switch (EVP_PKEY_key_type(pKey)) {
+ switch (EVP_PKEY_type(pKey->type)) {
case EVP_PKEY_RSA:
t = SSL_ALGO_RSA;
break;
case EVP_PKEY_DSA:
t = SSL_ALGO_DSA;
break;
+#ifndef OPENSSL_NO_EC
+ case EVP_PKEY_EC:
+ t = SSL_ALGO_ECC;
+ break;
+#endif
default:
break;
}
}
-#ifdef OPENSSL_VERSION_NUMBER
- /* Only refcounted in OpenSSL */
if (pFreeKey != NULL)
EVP_PKEY_free(pFreeKey);
-#endif
return t;
}
@@ -174,6 +178,11 @@ char *ssl_util_algotypestr(ssl_algo_t t)
case SSL_ALGO_DSA:
cp = "DSA";
break;
+#ifndef OPENSSL_NO_EC
+ case SSL_ALGO_ECC:
+ cp = "ECC";
+ break;
+#endif
default:
break;
}
@@ -206,14 +215,14 @@ unsigned char *ssl_asn1_table_set(apr_hash_t *table,
}
}
else {
- asn1 = malloc(sizeof(*asn1));
+ asn1 = ap_malloc(sizeof(*asn1));
asn1->source_mtime = 0; /* used as a note for encrypted private keys */
asn1->cpData = NULL;
}
asn1->nData = length;
if (!asn1->cpData) {
- asn1->cpData = malloc(length);
+ asn1->cpData = ap_malloc(length);
}
apr_hash_set(table, key, klen, asn1);
@@ -245,7 +254,11 @@ void ssl_asn1_table_unset(apr_hash_t *table,
apr_hash_set(table, key, klen, NULL);
}
+#ifndef OPENSSL_NO_EC
+static const char *ssl_asn1_key_types[] = {"RSA", "DSA", "ECC"};
+#else
static const char *ssl_asn1_key_types[] = {"RSA", "DSA"};
+#endif
const char *ssl_asn1_keystr(int keytype)
{
@@ -265,6 +278,56 @@ const char *ssl_asn1_table_keyfmt(apr_pool_t *p,
return apr_pstrcat(p, id, ":", keystr, NULL);
}
+STACK_OF(X509) *ssl_read_pkcs7(server_rec *s, const char *pkcs7)
+{
+ PKCS7 *p7;
+ STACK_OF(X509) *certs = NULL;
+ FILE *f;
+
+ f = fopen(pkcs7, "r");
+ if (!f) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02212) "Can't open %s", pkcs7);
+ ssl_die();
+ }
+
+ p7 = PEM_read_PKCS7(f, NULL, NULL, NULL);
+ if (!p7) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02274)
+ "Can't read PKCS7 object %s", pkcs7);
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_CRIT, s);
+ exit(1);
+ }
+
+ switch (OBJ_obj2nid(p7->type)) {
+ case NID_pkcs7_signed:
+ certs = p7->d.sign->cert;
+ p7->d.sign->cert = NULL;
+ PKCS7_free(p7);
+ break;
+
+ case NID_pkcs7_signedAndEnveloped:
+ certs = p7->d.signed_and_enveloped->cert;
+ p7->d.signed_and_enveloped->cert = NULL;
+ PKCS7_free(p7);
+ break;
+
+ default:
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02213)
+ "Don't understand PKCS7 file %s", pkcs7);
+ ssl_die();
+ }
+
+ if (!certs) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(02214)
+ "No certificates in %s", pkcs7);
+ ssl_die();
+ }
+
+ fclose(f);
+
+ return certs;
+}
+
#if APR_HAS_THREADS
/*
@@ -274,18 +337,8 @@ const char *ssl_asn1_table_keyfmt(apr_pool_t *p,
static apr_thread_mutex_t **lock_cs;
static int lock_num_locks;
-#ifdef HAVE_SSLC
-#if SSLC_VERSION_NUMBER >= 0x2000
-static int ssl_util_thr_lock(int mode, int type,
- char *file, int line)
-#else
-static void ssl_util_thr_lock(int mode, int type,
- char *file, int line)
-#endif
-#else
static void ssl_util_thr_lock(int mode, int type,
const char *file, int line)
-#endif
{
if (type < lock_num_locks) {
if (mode & CRYPTO_LOCK) {
@@ -294,21 +347,13 @@ static void ssl_util_thr_lock(int mode, int type,
else {
apr_thread_mutex_unlock(lock_cs[type]);
}
-#ifdef HAVE_SSLC
-#if SSLC_VERSION_NUMBER >= 0x2000
- return 1;
- }
- else {
- return -1;
-#endif
-#endif
}
}
/* Dynamic lock structure */
struct CRYPTO_dynlock_value {
apr_pool_t *pool;
- const char* file;
+ const char* file;
int line;
apr_thread_mutex_t *mutex;
};
@@ -319,45 +364,45 @@ apr_pool_t *dynlockpool = NULL;
/*
* Dynamic lock creation callback
*/
-static struct CRYPTO_dynlock_value *ssl_dyn_create_function(const char *file,
+static struct CRYPTO_dynlock_value *ssl_dyn_create_function(const char *file,
int line)
{
struct CRYPTO_dynlock_value *value;
apr_pool_t *p;
apr_status_t rv;
- /*
+ /*
* We need a pool to allocate our mutex. Since we can't clear
* allocated memory from a pool, create a subpool that we can blow
- * away in the destruction callback.
+ * away in the destruction callback.
*/
rv = apr_pool_create(&p, dynlockpool);
if (rv != APR_SUCCESS) {
- ap_log_perror(file, line, APLOG_ERR, rv, dynlockpool,
- "Failed to create subpool for dynamic lock");
+ ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_ERR, rv, dynlockpool,
+ APLOGNO(02183) "Failed to create subpool for dynamic lock");
return NULL;
}
- ap_log_perror(file, line, APLOG_DEBUG, 0, p,
+ ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE1, 0, p,
"Creating dynamic lock");
-
- value = (struct CRYPTO_dynlock_value *)apr_palloc(p,
+
+ value = (struct CRYPTO_dynlock_value *)apr_palloc(p,
sizeof(struct CRYPTO_dynlock_value));
if (!value) {
- ap_log_perror(file, line, APLOG_ERR, 0, p,
- "Failed to allocate dynamic lock structure");
+ ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_ERR, 0, p,
+ APLOGNO(02185) "Failed to allocate dynamic lock structure");
return NULL;
}
-
+
value->pool = p;
/* Keep our own copy of the place from which we were created,
using our own pool. */
value->file = apr_pstrdup(p, file);
value->line = line;
- rv = apr_thread_mutex_create(&(value->mutex), APR_THREAD_MUTEX_DEFAULT,
+ rv = apr_thread_mutex_create(&(value->mutex), APR_THREAD_MUTEX_DEFAULT,
p);
if (rv != APR_SUCCESS) {
- ap_log_perror(file, line, APLOG_ERR, rv, p,
+ ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_ERR, rv, p, APLOGNO(02186)
"Failed to create thread mutex for dynamic lock");
apr_pool_destroy(p);
return NULL;
@@ -375,17 +420,17 @@ static void ssl_dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l,
apr_status_t rv;
if (mode & CRYPTO_LOCK) {
- ap_log_perror(file, line, APLOG_DEBUG, 0, l->pool,
+ ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE3, 0, l->pool,
"Acquiring mutex %s:%d", l->file, l->line);
rv = apr_thread_mutex_lock(l->mutex);
- ap_log_perror(file, line, APLOG_DEBUG, rv, l->pool,
+ ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE3, rv, l->pool,
"Mutex %s:%d acquired!", l->file, l->line);
}
else {
- ap_log_perror(file, line, APLOG_DEBUG, 0, l->pool,
+ ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE3, 0, l->pool,
"Releasing mutex %s:%d", l->file, l->line);
rv = apr_thread_mutex_unlock(l->mutex);
- ap_log_perror(file, line, APLOG_DEBUG, rv, l->pool,
+ ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE3, rv, l->pool,
"Mutex %s:%d released!", l->file, l->line);
}
}
@@ -393,18 +438,18 @@ static void ssl_dyn_lock_function(int mode, struct CRYPTO_dynlock_value *l,
/*
* Dynamic lock destruction callback
*/
-static void ssl_dyn_destroy_function(struct CRYPTO_dynlock_value *l,
+static void ssl_dyn_destroy_function(struct CRYPTO_dynlock_value *l,
const char *file, int line)
{
apr_status_t rv;
- ap_log_perror(file, line, APLOG_DEBUG, 0, l->pool,
+ ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_TRACE1, 0, l->pool,
"Destroying dynamic lock %s:%d", l->file, l->line);
rv = apr_thread_mutex_destroy(l->mutex);
if (rv != APR_SUCCESS) {
- ap_log_perror(file, line, APLOG_ERR, rv, l->pool,
- "Failed to destroy mutex for dynamic lock %s:%d",
- l->file, l->line);
+ ap_log_perror(file, line, APLOG_MODULE_INDEX, APLOG_ERR, rv, l->pool,
+ APLOGNO(02192) "Failed to destroy mutex for dynamic "
+ "lock %s:%d", l->file, l->line);
}
/* Trust that whomever owned the CRYPTO_dynlock_value we were
@@ -435,11 +480,11 @@ static apr_status_t ssl_util_thread_cleanup(void *data)
{
CRYPTO_set_locking_callback(NULL);
CRYPTO_set_id_callback(NULL);
-
+
CRYPTO_set_dynlock_create_callback(NULL);
CRYPTO_set_dynlock_lock_callback(NULL);
CRYPTO_set_dynlock_destroy_callback(NULL);
-
+
dynlockpool = NULL;
/* Let the registered mutex cleanups do their own thing
@@ -461,9 +506,9 @@ void ssl_util_thread_setup(apr_pool_t *p)
CRYPTO_set_id_callback(ssl_util_thr_id);
CRYPTO_set_locking_callback(ssl_util_thr_lock);
-
+
/* Set up dynamic locking scaffolding for OpenSSL to use at its
- * convenience.
+ * convenience.
*/
dynlockpool = p;
CRYPTO_set_dynlock_create_callback(ssl_dyn_create_function);
diff --git a/modules/ssl/ssl_util_ocsp.c b/modules/ssl/ssl_util_ocsp.c
new file mode 100644
index 00000000..94ef4cd0
--- /dev/null
+++ b/modules/ssl/ssl_util_ocsp.c
@@ -0,0 +1,308 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* This file implements an OCSP client including a toy HTTP/1.0
+ * client. Once httpd depends on a real HTTP client library, most of
+ * this can be thrown away. */
+
+#include "ssl_private.h"
+
+#ifndef OPENSSL_NO_OCSP
+
+#include "apr_buckets.h"
+#include "apr_uri.h"
+
+/* Serialize an OCSP request which will be sent to the responder at
+ * given URI to a memory BIO object, which is returned. */
+static BIO *serialize_request(OCSP_REQUEST *req, const apr_uri_t *uri)
+{
+ BIO *bio;
+ int len;
+
+ len = i2d_OCSP_REQUEST(req, NULL);
+
+ bio = BIO_new(BIO_s_mem());
+
+ BIO_printf(bio, "POST %s%s%s HTTP/1.0\r\n"
+ "Host: %s:%d\r\n"
+ "Content-Type: application/ocsp-request\r\n"
+ "Content-Length: %d\r\n"
+ "\r\n",
+ uri->path ? uri->path : "/",
+ uri->query ? "?" : "", uri->query ? uri->query : "",
+ uri->hostname, uri->port, len);
+
+ if (i2d_OCSP_REQUEST_bio(bio, req) != 1) {
+ BIO_free(bio);
+ return NULL;
+ }
+
+ return bio;
+}
+
+/* Send the OCSP request serialized into BIO 'request' to the
+ * responder at given server given by URI. Returns socket object or
+ * NULL on error. */
+static apr_socket_t *send_request(BIO *request, const apr_uri_t *uri,
+ apr_interval_time_t timeout,
+ conn_rec *c, apr_pool_t *p)
+{
+ apr_status_t rv;
+ apr_sockaddr_t *sa;
+ apr_socket_t *sd;
+ char buf[HUGE_STRING_LEN];
+ int len;
+
+ rv = apr_sockaddr_info_get(&sa, uri->hostname, APR_UNSPEC, uri->port, 0, p);
+ if (rv) {
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(01972)
+ "could not resolve address of OCSP responder %s",
+ uri->hostinfo);
+ return NULL;
+ }
+
+ /* establish a connection to the OCSP responder */
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(01973)
+ "connecting to OCSP responder '%s'", uri->hostinfo);
+
+ /* Cycle through address until a connect() succeeds. */
+ for (; sa; sa = sa->next) {
+ rv = apr_socket_create(&sd, sa->family, SOCK_STREAM, APR_PROTO_TCP, p);
+ if (rv == APR_SUCCESS) {
+ apr_socket_timeout_set(sd, timeout);
+
+ rv = apr_socket_connect(sd, sa);
+ if (rv == APR_SUCCESS) {
+ break;
+ }
+ apr_socket_close(sd);
+ }
+ }
+
+ if (sa == NULL) {
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(01974)
+ "could not connect to OCSP responder '%s'",
+ uri->hostinfo);
+ apr_socket_close(sd);
+ return NULL;
+ }
+
+ /* send the request and get a response */
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(01975)
+ "sending request to OCSP responder");
+
+ while ((len = BIO_read(request, buf, sizeof buf)) > 0) {
+ char *wbuf = buf;
+ apr_size_t remain = len;
+
+ do {
+ apr_size_t wlen = remain;
+
+ rv = apr_socket_send(sd, wbuf, &wlen);
+ wbuf += remain;
+ remain -= wlen;
+ } while (rv == APR_SUCCESS && remain > 0);
+
+ if (rv) {
+ apr_socket_close(sd);
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(01976)
+ "failed to send request to OCSP responder '%s'",
+ uri->hostinfo);
+ return NULL;
+ }
+ }
+
+ return sd;
+}
+
+/* Return a pool-allocated NUL-terminated line, with CRLF stripped,
+ * read from brigade 'bbin' using 'bbout' as temporary storage. */
+static char *get_line(apr_bucket_brigade *bbout, apr_bucket_brigade *bbin,
+ conn_rec *c, apr_pool_t *p)
+{
+ apr_status_t rv;
+ apr_size_t len;
+ char *line;
+
+ apr_brigade_cleanup(bbout);
+
+ rv = apr_brigade_split_line(bbout, bbin, APR_BLOCK_READ, 8192);
+ if (rv) {
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(01977)
+ "failed reading line from OCSP server");
+ return NULL;
+ }
+
+ rv = apr_brigade_pflatten(bbout, &line, &len, p);
+ if (rv) {
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(01978)
+ "failed reading line from OCSP server");
+ return NULL;
+ }
+
+ if (len && line[len-1] != APR_ASCII_LF) {
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(01979)
+ "response header line too long from OCSP server");
+ return NULL;
+ }
+
+ line[len-1] = '\0';
+ if (len > 1 && line[len-2] == APR_ASCII_CR) {
+ line[len-2] = '\0';
+ }
+
+ return line;
+}
+
+/* Maximum values to prevent eating RAM forever. */
+#define MAX_HEADERS (256)
+#define MAX_CONTENT (2048 * 1024)
+
+/* Read the OCSP response from the socket 'sd', using temporary memory
+ * BIO 'bio', and return the decoded OCSP response object, or NULL on
+ * error. */
+static OCSP_RESPONSE *read_response(apr_socket_t *sd, BIO *bio, conn_rec *c,
+ apr_pool_t *p)
+{
+ apr_bucket_brigade *bb, *tmpbb;
+ OCSP_RESPONSE *response;
+ char *line;
+ apr_size_t count;
+ apr_int64_t code;
+
+ /* Using brigades for response parsing is much simpler than using
+ * apr_socket_* directly. */
+ bb = apr_brigade_create(p, c->bucket_alloc);
+ tmpbb = apr_brigade_create(p, c->bucket_alloc);
+ APR_BRIGADE_INSERT_TAIL(bb, apr_bucket_socket_create(sd, c->bucket_alloc));
+
+ line = get_line(tmpbb, bb, c, p);
+ if (!line || strncmp(line, "HTTP/", 5)
+ || (line = ap_strchr(line, ' ')) == NULL
+ || (code = apr_atoi64(++line)) < 200 || code > 299) {
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(01980)
+ "bad response from OCSP server: %s",
+ line ? line : "(none)");
+ return NULL;
+ }
+
+ /* Read till end of headers; don't have to even bother parsing the
+ * Content-Length since the server is obliged to close the
+ * connection after the response anyway for HTTP/1.0. */
+ count = 0;
+ while ((line = get_line(tmpbb, bb, c, p)) != NULL && line[0]
+ && ++count < MAX_HEADERS) {
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(01981)
+ "OCSP response header: %s", line);
+ }
+
+ if (count == MAX_HEADERS) {
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(01982)
+ "could not read response headers from OCSP server, "
+ "exceeded maximum count (%u)", MAX_HEADERS);
+ return NULL;
+ }
+ else if (!line) {
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(01983)
+ "could not read response header from OCSP server");
+ return NULL;
+ }
+
+ /* Read the response body into the memory BIO. */
+ count = 0;
+ while (!APR_BRIGADE_EMPTY(bb)) {
+ const char *data;
+ apr_size_t len;
+ apr_status_t rv;
+ apr_bucket *e = APR_BRIGADE_FIRST(bb);
+
+ rv = apr_bucket_read(e, &data, &len, APR_BLOCK_READ);
+ if (rv == APR_EOF || (rv == APR_SUCCESS && len == 0)) {
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(01984)
+ "OCSP response: got EOF");
+ break;
+ }
+ if (rv != APR_SUCCESS) {
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(01985)
+ "error reading response from OCSP server");
+ return NULL;
+ }
+ count += len;
+ if (count > MAX_CONTENT) {
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, rv, c, APLOGNO(01986)
+ "OCSP response size exceeds %u byte limit",
+ MAX_CONTENT);
+ return NULL;
+ }
+ ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c, APLOGNO(01987)
+ "OCSP response: got %" APR_SIZE_T_FMT
+ " bytes, %" APR_SIZE_T_FMT " total", len, count);
+
+ BIO_write(bio, data, (int)len);
+ apr_bucket_delete(e);
+ }
+
+ apr_brigade_destroy(bb);
+ apr_brigade_destroy(tmpbb);
+
+ /* Finally decode the OCSP response from what's stored in the
+ * bio. */
+ response = d2i_OCSP_RESPONSE_bio(bio, NULL);
+ if (response == NULL) {
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(01988)
+ "failed to decode OCSP response data");
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, mySrvFromConn(c));
+ }
+
+ return response;
+}
+
+OCSP_RESPONSE *modssl_dispatch_ocsp_request(const apr_uri_t *uri,
+ apr_interval_time_t timeout,
+ OCSP_REQUEST *request,
+ conn_rec *c, apr_pool_t *p)
+{
+ OCSP_RESPONSE *response = NULL;
+ apr_socket_t *sd;
+ BIO *bio;
+
+ bio = serialize_request(request, uri);
+ if (bio == NULL) {
+ ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(01989)
+ "could not serialize OCSP request");
+ ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, mySrvFromConn(c));
+ return NULL;
+ }
+
+ sd = send_request(bio, uri, timeout, c, p);
+ if (sd == NULL) {
+ /* Errors already logged. */
+ BIO_free(bio);
+ return NULL;
+ }
+
+ /* Clear the BIO contents, ready for the response. */
+ (void)BIO_reset(bio);
+
+ response = read_response(sd, bio, c, p);
+
+ apr_socket_close(sd);
+ BIO_free(bio);
+
+ return response;
+}
+
+#endif /* HAVE_OCSP */
diff --git a/modules/ssl/ssl_util_ssl.c b/modules/ssl/ssl_util_ssl.c
index a06b6504..5022d0da 100644
--- a/modules/ssl/ssl_util_ssl.c
+++ b/modules/ssl/ssl_util_ssl.c
@@ -74,7 +74,7 @@ void SSL_set_app_data2(SSL *ssl, void *arg)
** _________________________________________________________________
*/
-X509 *SSL_read_X509(char* filename, X509 **x509, modssl_read_bio_cb_fn *cb)
+X509 *SSL_read_X509(char* filename, X509 **x509, pem_password_cb *cb)
{
X509 *rc;
BIO *bioS;
@@ -83,7 +83,7 @@ X509 *SSL_read_X509(char* filename, X509 **x509, modssl_read_bio_cb_fn *cb)
/* 1. try PEM (= DER+Base64+headers) */
if ((bioS=BIO_new_file(filename, "r")) == NULL)
return NULL;
- rc = modssl_PEM_read_bio_X509 (bioS, x509, cb, NULL);
+ rc = PEM_read_bio_X509 (bioS, x509, cb, NULL);
BIO_free(bioS);
if (rc == NULL) {
@@ -115,17 +115,7 @@ X509 *SSL_read_X509(char* filename, X509 **x509, modssl_read_bio_cb_fn *cb)
return rc;
}
-#if SSL_LIBRARY_VERSION <= 0x00904100
-static EVP_PKEY *d2i_PrivateKey_bio(BIO *bio, EVP_PKEY **key)
-{
- return ((EVP_PKEY *)ASN1_d2i_bio(
- (char *(*)())EVP_PKEY_new,
- (char *(*)())d2i_PrivateKey,
- (bio), (unsigned char **)(key)));
-}
-#endif
-
-EVP_PKEY *SSL_read_PrivateKey(char* filename, EVP_PKEY **key, modssl_read_bio_cb_fn *cb, void *s)
+EVP_PKEY *SSL_read_PrivateKey(char* filename, EVP_PKEY **key, pem_password_cb *cb, void *s)
{
EVP_PKEY *rc;
BIO *bioS;
@@ -134,7 +124,7 @@ EVP_PKEY *SSL_read_PrivateKey(char* filename, EVP_PKEY **key, modssl_read_bio_cb
/* 1. try PEM (= DER+Base64+headers) */
if ((bioS=BIO_new_file(filename, "r")) == NULL)
return NULL;
- rc = modssl_PEM_read_bio_PrivateKey(bioS, key, cb, s);
+ rc = PEM_read_bio_PrivateKey(bioS, key, cb, s);
BIO_free(bioS);
if (rc == NULL) {
@@ -194,55 +184,6 @@ int SSL_smart_shutdown(SSL *ssl)
/* _________________________________________________________________
**
-** Certificate Revocation List (CRL) Storage
-** _________________________________________________________________
-*/
-
-X509_STORE *SSL_X509_STORE_create(char *cpFile, char *cpPath)
-{
- X509_STORE *pStore;
- X509_LOOKUP *pLookup;
- int rv = 1;
-
- ERR_clear_error();
-
- if (cpFile == NULL && cpPath == NULL)
- return NULL;
- if ((pStore = X509_STORE_new()) == NULL)
- return NULL;
- if (cpFile != NULL) {
- pLookup = X509_STORE_add_lookup(pStore, X509_LOOKUP_file());
- if (pLookup == NULL) {
- X509_STORE_free(pStore);
- return NULL;
- }
- rv = X509_LOOKUP_load_file(pLookup, cpFile, X509_FILETYPE_PEM);
- }
- if (cpPath != NULL && rv == 1) {
- pLookup = X509_STORE_add_lookup(pStore, X509_LOOKUP_hash_dir());
- if (pLookup == NULL) {
- X509_STORE_free(pStore);
- return NULL;
- }
- rv = X509_LOOKUP_add_dir(pLookup, cpPath, X509_FILETYPE_PEM);
- }
- return rv == 1 ? pStore : NULL;
-}
-
-int SSL_X509_STORE_lookup(X509_STORE *pStore, int nType,
- X509_NAME *pName, X509_OBJECT *pObj)
-{
- X509_STORE_CTX pStoreCtx;
- int rc;
-
- X509_STORE_CTX_init(&pStoreCtx, pStore, NULL, NULL);
- rc = X509_STORE_get_by_subject(&pStoreCtx, nType, pName, pObj);
- X509_STORE_CTX_cleanup(&pStoreCtx);
- return rc;
-}
-
-/* _________________________________________________________________
-**
** Cipher Suite Spec String Creation
** _________________________________________________________________
*/
@@ -275,7 +216,7 @@ char *SSL_make_ciphersuite(apr_pool_t *p, SSL *ssl)
memcpy(cp, SSL_CIPHER_get_name(c), l);
cp += l;
*cp++ = '/';
- *cp++ = (SSL_CIPHER_get_valid(c) == 1 ? '1' : '0');
+ *cp++ = (c->valid == 1 ? '1' : '0');
*cp++ = ':';
}
*(cp-1) = NUL;
@@ -291,50 +232,35 @@ char *SSL_make_ciphersuite(apr_pool_t *p, SSL *ssl)
/* check whether cert contains extended key usage with a SGC tag */
BOOL SSL_X509_isSGC(X509 *cert)
{
-#ifdef HAVE_SSL_X509V3_EXT_d2i
- X509_EXTENSION *ext;
int ext_nid;
EXTENDED_KEY_USAGE *sk;
BOOL is_sgc;
- int idx;
int i;
is_sgc = FALSE;
- idx = X509_get_ext_by_NID(cert, NID_ext_key_usage, -1);
- if (idx >= 0) {
- ext = X509_get_ext(cert, idx);
- if ((sk = (EXTENDED_KEY_USAGE *)X509V3_EXT_d2i(ext)) != NULL) {
- for (i = 0; i < sk_ASN1_OBJECT_num(sk); i++) {
- ext_nid = OBJ_obj2nid((ASN1_OBJECT *)sk_ASN1_OBJECT_value(sk, i));
- if (ext_nid == NID_ms_sgc || ext_nid == NID_ns_sgc) {
- is_sgc = TRUE;
- break;
- }
+ sk = X509_get_ext_d2i(cert, NID_ext_key_usage, NULL, NULL);
+ if (sk) {
+ for (i = 0; i < sk_ASN1_OBJECT_num(sk); i++) {
+ ext_nid = OBJ_obj2nid(sk_ASN1_OBJECT_value(sk, i));
+ if (ext_nid == NID_ms_sgc || ext_nid == NID_ns_sgc) {
+ is_sgc = TRUE;
+ break;
}
}
+ EXTENDED_KEY_USAGE_free(sk);
}
return is_sgc;
-#else
- return FALSE;
-#endif
}
/* retrieve basic constraints ingredients */
BOOL SSL_X509_getBC(X509 *cert, int *ca, int *pathlen)
{
-#ifdef HAVE_SSL_X509V3_EXT_d2i
- X509_EXTENSION *ext;
BASIC_CONSTRAINTS *bc;
- int idx;
BIGNUM *bn = NULL;
char *cp;
- if ((idx = X509_get_ext_by_NID(cert, NID_basic_constraints, -1)) < 0)
- return FALSE;
- ext = X509_get_ext(cert, idx);
- if (ext == NULL)
- return FALSE;
- if ((bc = (BASIC_CONSTRAINTS *)X509V3_EXT_d2i(ext)) == NULL)
+ bc = X509_get_ext_d2i(cert, NID_basic_constraints, NULL, NULL);
+ if (bc == NULL)
return FALSE;
*ca = bc->ca;
*pathlen = -1 /* unlimited */;
@@ -349,37 +275,108 @@ BOOL SSL_X509_getBC(X509 *cert, int *ca, int *pathlen)
}
BASIC_CONSTRAINTS_free(bc);
return TRUE;
-#else
- return FALSE;
-#endif
}
-/* retrieve subject CommonName of certificate */
-BOOL SSL_X509_getCN(apr_pool_t *p, X509 *xs, char **cppCN)
+/* convert a NAME_ENTRY to UTF8 string */
+char *SSL_X509_NAME_ENTRY_to_string(apr_pool_t *p, X509_NAME_ENTRY *xsne)
+{
+ char *result = NULL;
+ BIO* bio;
+ int len;
+
+ if ((bio = BIO_new(BIO_s_mem())) == NULL)
+ return NULL;
+ ASN1_STRING_print_ex(bio, X509_NAME_ENTRY_get_data(xsne),
+ ASN1_STRFLGS_ESC_CTRL|ASN1_STRFLGS_UTF8_CONVERT);
+ len = BIO_pending(bio);
+ result = apr_palloc(p, len+1);
+ len = BIO_read(bio, result, len);
+ result[len] = NUL;
+ BIO_free(bio);
+ ap_xlate_proto_from_ascii(result, len);
+ return result;
+}
+
+/*
+ * convert an X509_NAME to an RFC 2253 formatted string, optionally truncated
+ * to maxlen characters (specify a maxlen of 0 for no length limit)
+ */
+char *SSL_X509_NAME_to_string(apr_pool_t *p, X509_NAME *dn, unsigned int maxlen)
{
- X509_NAME *xsn;
- X509_NAME_ENTRY *xsne;
- int i, nid;
- unsigned char *data_ptr;
- int data_len;
-
- xsn = X509_get_subject_name(xs);
- for (i = 0; i < sk_X509_NAME_ENTRY_num((STACK_OF(X509_NAME_ENTRY) *)
- X509_NAME_get_entries(xsn)); i++) {
- xsne = sk_X509_NAME_ENTRY_value((STACK_OF(X509_NAME_ENTRY) *)
- X509_NAME_get_entries(xsn), i);
- nid = OBJ_obj2nid((ASN1_OBJECT *)X509_NAME_ENTRY_get_object(xsne));
- if (nid == NID_commonName) {
- data_ptr = X509_NAME_ENTRY_get_data_ptr(xsne);
- data_len = X509_NAME_ENTRY_get_data_len(xsne);
- *cppCN = apr_palloc(p, data_len+1);
- apr_cpystrn(*cppCN, (char *)data_ptr, data_len+1);
- (*cppCN)[data_len] = NUL;
- ap_xlate_proto_from_ascii(*cppCN, data_len);
- return TRUE;
+ char *result = NULL;
+ BIO *bio;
+ int len;
+
+ if ((bio = BIO_new(BIO_s_mem())) == NULL)
+ return NULL;
+ X509_NAME_print_ex(bio, dn, 0, XN_FLAG_RFC2253);
+ len = BIO_pending(bio);
+ if (len > 0) {
+ result = apr_palloc(p, maxlen ? maxlen+1 : len+1);
+ if (maxlen && maxlen < len) {
+ len = BIO_read(bio, result, maxlen);
+ if (maxlen > 2) {
+ /* insert trailing ellipsis if there's enough space */
+ apr_snprintf(result + maxlen - 3, 4, "...");
+ }
+ } else {
+ len = BIO_read(bio, result, len);
}
+ result[len] = NUL;
+ }
+ BIO_free(bio);
+
+ return result;
+}
+
+/* return an array of (RFC 6125 coined) DNS-IDs and CN-IDs in a certificate */
+BOOL SSL_X509_getIDs(apr_pool_t *p, X509 *x509, apr_array_header_t **ids)
+{
+ STACK_OF(GENERAL_NAME) *names;
+ BIO *bio;
+ X509_NAME *subj;
+ char **cpp;
+ int i, n;
+
+ if (!x509 || !(*ids = apr_array_make(p, 0, sizeof(char *)))) {
+ *ids = NULL;
+ return FALSE;
+ }
+
+ /* First, the DNS-IDs (dNSName entries in the subjectAltName extension) */
+ if ((names = X509_get_ext_d2i(x509, NID_subject_alt_name, NULL, NULL)) &&
+ (bio = BIO_new(BIO_s_mem()))) {
+ GENERAL_NAME *name;
+
+ for (i = 0; i < sk_GENERAL_NAME_num(names); i++) {
+ name = sk_GENERAL_NAME_value(names, i);
+ if (name->type == GEN_DNS) {
+ ASN1_STRING_print_ex(bio, name->d.ia5, ASN1_STRFLGS_ESC_CTRL|
+ ASN1_STRFLGS_UTF8_CONVERT);
+ n = BIO_pending(bio);
+ if (n > 0) {
+ cpp = (char **)apr_array_push(*ids);
+ *cpp = apr_palloc(p, n+1);
+ n = BIO_read(bio, *cpp, n);
+ (*cpp)[n] = NUL;
+ }
+ }
+ }
+ BIO_free(bio);
}
- return FALSE;
+
+ if (names)
+ sk_GENERAL_NAME_free(names);
+
+ /* Second, the CN-IDs (commonName attributes in the subject DN) */
+ subj = X509_get_subject_name(x509);
+ i = -1;
+ while ((i = X509_NAME_get_index_by_NID(subj, NID_commonName, i)) != -1) {
+ cpp = (char **)apr_array_push(*ids);
+ *cpp = SSL_X509_NAME_ENTRY_to_string(p, X509_NAME_get_entry(subj, i));
+ }
+
+ return apr_is_empty_array(*ids) ? FALSE : TRUE;
}
/* _________________________________________________________________
@@ -398,14 +395,14 @@ BOOL SSL_X509_INFO_load_file(apr_pool_t *ptemp,
return FALSE;
}
- if (BIO_read_filename(in, MODSSL_PCHAR_CAST filename) <= 0) {
+ if (BIO_read_filename(in, filename) <= 0) {
BIO_free(in);
return FALSE;
}
ERR_clear_error();
- modssl_PEM_X509_INFO_read_bio(in, sk, NULL, NULL);
+ PEM_X509_INFO_read_bio(in, sk, NULL, NULL);
BIO_free(in);
@@ -461,7 +458,7 @@ BOOL SSL_X509_INFO_load_path(apr_pool_t *ptemp,
* should be sent to the peer in the SSL Certificate message.
*/
int SSL_CTX_use_certificate_chain(
- SSL_CTX *ctx, char *file, int skipfirst, modssl_read_bio_cb_fn *cb)
+ SSL_CTX *ctx, char *file, int skipfirst, pem_password_cb *cb)
{
BIO *bio;
X509 *x509;
@@ -477,21 +474,21 @@ int SSL_CTX_use_certificate_chain(
}
/* optionally skip a leading server certificate */
if (skipfirst) {
- if ((x509 = modssl_PEM_read_bio_X509(bio, NULL, cb, NULL)) == NULL) {
+ if ((x509 = PEM_read_bio_X509(bio, NULL, cb, NULL)) == NULL) {
BIO_free(bio);
return -1;
}
X509_free(x509);
}
/* free a perhaps already configured extra chain */
- extra_certs=SSL_CTX_get_extra_certs(ctx);
+ extra_certs = ctx->extra_certs;
if (extra_certs != NULL) {
sk_X509_pop_free((STACK_OF(X509) *)extra_certs, X509_free);
- SSL_CTX_set_extra_certs(ctx,NULL);
+ ctx->extra_certs = NULL;
}
/* create new extra chain by loading the certs */
n = 0;
- while ((x509 = modssl_PEM_read_bio_X509(bio, NULL, cb, NULL)) != NULL) {
+ while ((x509 = PEM_read_bio_X509(bio, NULL, cb, NULL)) != NULL) {
if (!SSL_CTX_add_extra_chain_cert(ctx, x509)) {
X509_free(x509);
BIO_free(bio);
@@ -532,44 +529,3 @@ char *SSL_SESSION_id2sz(unsigned char *id, int idlen,
*cp = NUL;
return str;
}
-
-/* sslc+OpenSSL compat */
-
-int modssl_session_get_time(SSL_SESSION *session)
-{
-#ifdef OPENSSL_VERSION_NUMBER
- return SSL_SESSION_get_time(session);
-#else /* assume sslc */
- CRYPTO_TIME_T ct;
- SSL_SESSION_get_time(session, &ct);
- return CRYPTO_time_to_int(&ct);
-#endif
-}
-
-#ifndef SSLC_VERSION_NUMBER
-#define SSLC_VERSION_NUMBER 0x0000
-#endif
-
-DH *modssl_dh_configure(unsigned char *p, int plen,
- unsigned char *g, int glen)
-{
- DH *dh;
-
- if (!(dh = DH_new())) {
- return NULL;
- }
-
-#if defined(OPENSSL_VERSION_NUMBER) || (SSLC_VERSION_NUMBER < 0x2000)
- dh->p = BN_bin2bn(p, plen, NULL);
- dh->g = BN_bin2bn(g, glen, NULL);
- if (!(dh->p && dh->g)) {
- DH_free(dh);
- return NULL;
- }
-#else
- R_EITEMS_add(dh->data, PK_TYPE_DH, PK_DH_P, 0, p, plen, R_EITEMS_PF_COPY);
- R_EITEMS_add(dh->data, PK_TYPE_DH, PK_DH_G, 0, g, glen, R_EITEMS_PF_COPY);
-#endif
-
- return dh;
-}
diff --git a/modules/ssl/ssl_util_ssl.h b/modules/ssl/ssl_util_ssl.h
index 04bcbdc2..db2a2e30 100644
--- a/modules/ssl/ssl_util_ssl.h
+++ b/modules/ssl/ssl_util_ssl.h
@@ -35,30 +35,13 @@
#define __SSL_UTIL_SSL_H__
/**
- * Determine SSL library version number
+ * SSL library version number
*/
-#define SSL_NIBBLE(x,n) ((x >> (n * 4)) & 0xF)
-#ifdef OPENSSL_VERSION_NUMBER
#define SSL_LIBRARY_VERSION OPENSSL_VERSION_NUMBER
#define SSL_LIBRARY_NAME "OpenSSL"
#define SSL_LIBRARY_TEXT OPENSSL_VERSION_TEXT
#define SSL_LIBRARY_DYNTEXT SSLeay_version(SSLEAY_VERSION)
-#elif defined(SSLC_VERSION_NUMBER)
-#define SSL_LIBRARY_VERSION SSLC_VERSION_NUMBER
-#define SSL_LIBRARY_NAME "SSL-C"
-#define SSL_LIBRARY_TEXT { 'S', 'S', 'L', '-', 'C', ' ', \
- '0' + SSL_NIBBLE(SSLC_VERSION_NUMBER,3), '.', \
- '0' + SSL_NIBBLE(SSLC_VERSION_NUMBER,2), '.', \
- '0' + SSL_NIBBLE(SSLC_VERSION_NUMBER,1), '.', \
- '0' + SSL_NIBBLE(SSLC_VERSION_NUMBER,0), 0 }
-#define SSL_LIBRARY_DYNTEXT SSLC_library_info(SSLC_INFO_VERSION)
-#elif !defined(SSL_LIBRARY_VERSION)
-#define SSL_LIBRARY_VERSION 0x0000
-#define SSL_LIBRARY_NAME "OtherSSL"
-#define SSL_LIBRARY_TEXT "OtherSSL 0.0.0 00 XXX 0000"
-#define SSL_LIBRARY_DYNTEXT "OtherSSL 0.0.0 00 XXX 0000"
-#endif
/**
* Maximum length of a DER encoded session.
@@ -71,32 +54,26 @@
#define SSL_SESSION_ID_STRING_LEN \
((SSL_MAX_SSL_SESSION_ID_LENGTH + 1) * 2)
-/**
+/**
* Additional Functions
*/
void SSL_init_app_data2_idx(void);
void *SSL_get_app_data2(SSL *);
void SSL_set_app_data2(SSL *, void *);
-X509 *SSL_read_X509(char *, X509 **, modssl_read_bio_cb_fn *);
-EVP_PKEY *SSL_read_PrivateKey(char *, EVP_PKEY **, modssl_read_bio_cb_fn *, void *);
+X509 *SSL_read_X509(char *, X509 **, pem_password_cb *);
+EVP_PKEY *SSL_read_PrivateKey(char *, EVP_PKEY **, pem_password_cb *, void *);
int SSL_smart_shutdown(SSL *ssl);
-X509_STORE *SSL_X509_STORE_create(char *, char *);
-int SSL_X509_STORE_lookup(X509_STORE *, int, X509_NAME *, X509_OBJECT *);
char *SSL_make_ciphersuite(apr_pool_t *, SSL *);
BOOL SSL_X509_isSGC(X509 *);
BOOL SSL_X509_getBC(X509 *, int *, int *);
-BOOL SSL_X509_getCN(apr_pool_t *, X509 *, char **);
+char *SSL_X509_NAME_ENTRY_to_string(apr_pool_t *p, X509_NAME_ENTRY *xsne);
+char *SSL_X509_NAME_to_string(apr_pool_t *, X509_NAME *, unsigned int);
+BOOL SSL_X509_getIDs(apr_pool_t *, X509 *, apr_array_header_t **);
BOOL SSL_X509_INFO_load_file(apr_pool_t *, STACK_OF(X509_INFO) *, const char *);
BOOL SSL_X509_INFO_load_path(apr_pool_t *, STACK_OF(X509_INFO) *, const char *);
-int SSL_CTX_use_certificate_chain(SSL_CTX *, char *, int, modssl_read_bio_cb_fn *);
+int SSL_CTX_use_certificate_chain(SSL_CTX *, char *, int, pem_password_cb *);
char *SSL_SESSION_id2sz(unsigned char *, int, char *, int);
-/** util functions for OpenSSL+sslc compat */
-int modssl_session_get_time(SSL_SESSION *session);
-
-DH *modssl_dh_configure(unsigned char *p, int plen,
- unsigned char *g, int glen);
-
#endif /* __SSL_UTIL_SSL_H__ */
/** @} */
diff --git a/modules/ssl/ssl_util_stapling.c b/modules/ssl/ssl_util_stapling.c
new file mode 100644
index 00000000..941fb285
--- /dev/null
+++ b/modules/ssl/ssl_util_stapling.c
@@ -0,0 +1,688 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* _ _
+ * _ __ ___ ___ __| | ___ ___| | mod_ssl
+ * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL
+ * | | | | | | (_) | (_| | \__ \__ \ |
+ * |_| |_| |_|\___/ \__,_|___|___/___/_|
+ * |_____|
+ * ssl_stapling.c
+ * OCSP Stapling Support
+ */
+ /* ``Where's the spoons?
+ Where's the spoons?
+ Where's the bloody spoons?''
+ -- Alexei Sayle */
+
+#include "ssl_private.h"
+#include "ap_mpm.h"
+#include "apr_thread_mutex.h"
+
+#ifdef HAVE_OCSP_STAPLING
+
+/**
+ * Maxiumum OCSP stapling response size. This should be the response for a
+ * single certificate and will typically include the responder certificate chain
+ * so 10K should be more than enough.
+ *
+ */
+
+#define MAX_STAPLING_DER 10240
+
+/* Cached info stored in certificate ex_info. */
+typedef struct {
+ /* Index in session cache SHA1 hash of certificate */
+ UCHAR idx[20];
+ /* Certificate ID for OCSP requests or NULL if ID cannot be determined */
+ OCSP_CERTID *cid;
+ /* Responder details */
+ char *uri;
+} certinfo;
+
+static void certinfo_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad,
+ int idx, long argl, void *argp)
+{
+ certinfo *cinf = ptr;
+
+ if (!cinf)
+ return;
+ if (cinf->uri)
+ OPENSSL_free(cinf->uri);
+ OPENSSL_free(cinf);
+}
+
+static int stapling_ex_idx = -1;
+
+void ssl_stapling_ex_init(void)
+{
+ if (stapling_ex_idx != -1)
+ return;
+ stapling_ex_idx = X509_get_ex_new_index(0, "X509 cached OCSP info", 0, 0,
+ certinfo_free);
+}
+
+static X509 *stapling_get_issuer(modssl_ctx_t *mctx, X509 *x)
+{
+ X509 *issuer = NULL;
+ int i;
+ X509_STORE *st = SSL_CTX_get_cert_store(mctx->ssl_ctx);
+ X509_STORE_CTX inctx;
+
+ for (i = 0; i < sk_X509_num(mctx->ssl_ctx->extra_certs); i++) {
+ issuer = sk_X509_value(mctx->ssl_ctx->extra_certs, i);
+ if (X509_check_issued(issuer, x) == X509_V_OK) {
+ CRYPTO_add(&issuer->references, 1, CRYPTO_LOCK_X509);
+ return issuer;
+ }
+ }
+
+ if (!X509_STORE_CTX_init(&inctx, st, NULL, NULL))
+ return 0;
+ if (X509_STORE_CTX_get1_issuer(&issuer, &inctx, x) <= 0)
+ issuer = NULL;
+ X509_STORE_CTX_cleanup(&inctx);
+ return issuer;
+
+}
+
+int ssl_stapling_init_cert(server_rec *s, modssl_ctx_t *mctx, X509 *x)
+{
+ certinfo *cinf;
+ X509 *issuer = NULL;
+ STACK_OF(OPENSSL_STRING) *aia = NULL;
+
+ if (x == NULL)
+ return 0;
+ cinf = X509_get_ex_data(x, stapling_ex_idx);
+ if (cinf) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02215)
+ "ssl_stapling_init_cert: certificate already initialized!");
+ return 0;
+ }
+ cinf = OPENSSL_malloc(sizeof(certinfo));
+ if (!cinf) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02216)
+ "ssl_stapling_init_cert: error allocating memory!");
+ return 0;
+ }
+ cinf->cid = NULL;
+ cinf->uri = NULL;
+ X509_set_ex_data(x, stapling_ex_idx, cinf);
+
+ issuer = stapling_get_issuer(mctx, x);
+
+ if (issuer == NULL) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02217)
+ "ssl_stapling_init_cert: Can't retrieve issuer certificate!");
+ return 0;
+ }
+
+ cinf->cid = OCSP_cert_to_id(NULL, x, issuer);
+ X509_free(issuer);
+ if (!cinf->cid)
+ return 0;
+ X509_digest(x, EVP_sha1(), cinf->idx, NULL);
+
+ aia = X509_get1_ocsp(x);
+ if (aia)
+ cinf->uri = sk_OPENSSL_STRING_pop(aia);
+ if (!cinf->uri && !mctx->stapling_force_url) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02218)
+ "ssl_stapling_init_cert: no responder URL");
+ }
+ if (aia)
+ X509_email_free(aia);
+ return 1;
+}
+
+static certinfo *stapling_get_cert_info(server_rec *s, modssl_ctx_t *mctx,
+ SSL *ssl)
+{
+ certinfo *cinf;
+ X509 *x;
+ x = SSL_get_certificate(ssl);
+ if (x == NULL)
+ return NULL;
+ cinf = X509_get_ex_data(x, stapling_ex_idx);
+ if (cinf && cinf->cid)
+ return cinf;
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01926)
+ "stapling_get_cert_info: stapling not supported for certificate");
+ return NULL;
+}
+
+/*
+ * OCSP response caching code. The response is preceded by a flag value
+ * which indicates whether the response was invalid when it was stored.
+ * the purpose of this flag is to avoid repeated queries to a server
+ * which has given an invalid response while allowing a response which
+ * has subsequently become invalid to be retried immediately.
+ *
+ * The key for the cache is the hash of the certificate the response
+ * is for.
+ */
+static BOOL stapling_cache_response(server_rec *s, modssl_ctx_t *mctx,
+ OCSP_RESPONSE *rsp, certinfo *cinf,
+ BOOL ok, apr_pool_t *pool)
+{
+ SSLModConfigRec *mc = myModConfig(s);
+ unsigned char resp_der[MAX_STAPLING_DER];
+ unsigned char *p;
+ int resp_derlen;
+ BOOL rv;
+ apr_time_t expiry;
+
+ resp_derlen = i2d_OCSP_RESPONSE(rsp, NULL) + 1;
+
+ if (resp_derlen <= 0) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01927)
+ "OCSP stapling response encode error??");
+ return FALSE;
+ }
+
+ if (resp_derlen > sizeof resp_der) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01928)
+ "OCSP stapling response too big (%u bytes)", resp_derlen);
+ return FALSE;
+ }
+
+ p = resp_der;
+
+ /* TODO: potential optimization; _timeout members as apr_interval_time_t */
+ if (ok == TRUE) {
+ *p++ = 1;
+ expiry = apr_time_from_sec(mctx->stapling_cache_timeout);
+ }
+ else {
+ *p++ = 0;
+ expiry = apr_time_from_sec(mctx->stapling_errcache_timeout);
+ }
+
+ expiry += apr_time_now();
+
+ i2d_OCSP_RESPONSE(rsp, &p);
+
+ rv = mc->stapling_cache->store(mc->stapling_cache_context, s,
+ cinf->idx, sizeof(cinf->idx),
+ expiry, resp_der, resp_derlen, pool);
+ if (rv != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01929)
+ "stapling_cache_response: OCSP response session store error!");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static BOOL stapling_get_cached_response(server_rec *s, OCSP_RESPONSE **prsp,
+ BOOL *pok, certinfo *cinf,
+ apr_pool_t *pool)
+{
+ SSLModConfigRec *mc = myModConfig(s);
+ apr_status_t rv;
+ OCSP_RESPONSE *rsp;
+ unsigned char resp_der[MAX_STAPLING_DER];
+ const unsigned char *p;
+ unsigned int resp_derlen = MAX_STAPLING_DER;
+
+ rv = mc->stapling_cache->retrieve(mc->stapling_cache_context, s,
+ cinf->idx, sizeof(cinf->idx),
+ resp_der, &resp_derlen, pool);
+ if (rv != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01930)
+ "stapling_get_cached_response: cache miss");
+ return TRUE;
+ }
+ if (resp_derlen <= 1) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01931)
+ "stapling_get_cached_response: response length invalid??");
+ return TRUE;
+ }
+ p = resp_der;
+ if (pok) {
+ if (*p)
+ *pok = TRUE;
+ else
+ *pok = FALSE;
+ }
+ p++;
+ resp_derlen--;
+ rsp = d2i_OCSP_RESPONSE(NULL, &p, resp_derlen);
+ if (!rsp) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01932)
+ "stapling_get_cached_response: response parse error??");
+ return TRUE;
+ }
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01933)
+ "stapling_get_cached_response: cache hit");
+
+ *prsp = rsp;
+
+ return TRUE;
+}
+
+static int stapling_set_response(SSL *ssl, OCSP_RESPONSE *rsp)
+{
+ int rspderlen;
+ unsigned char *rspder = NULL;
+
+ rspderlen = i2d_OCSP_RESPONSE(rsp, &rspder);
+ if (rspderlen <= 0)
+ return 0;
+ SSL_set_tlsext_status_ocsp_resp(ssl, rspder, rspderlen);
+ return 1;
+}
+
+static int stapling_check_response(server_rec *s, modssl_ctx_t *mctx,
+ certinfo *cinf, OCSP_RESPONSE *rsp,
+ BOOL *pok)
+{
+ int status, reason;
+ OCSP_BASICRESP *bs = NULL;
+ ASN1_GENERALIZEDTIME *rev, *thisupd, *nextupd;
+ int response_status = OCSP_response_status(rsp);
+
+ if (pok)
+ *pok = FALSE;
+ /* Check to see if response is an error. If so we automatically accept
+ * it because it would have expired from the cache if it was time to
+ * retry.
+ */
+ if (response_status != OCSP_RESPONSE_STATUS_SUCCESSFUL) {
+ if (mctx->stapling_return_errors)
+ return SSL_TLSEXT_ERR_OK;
+ else
+ return SSL_TLSEXT_ERR_NOACK;
+ }
+
+ bs = OCSP_response_get1_basic(rsp);
+ if (bs == NULL) {
+ /* If we can't parse response just pass it to client */
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01934)
+ "stapling_check_response: Error Parsing Response!");
+ return SSL_TLSEXT_ERR_OK;
+ }
+
+ if (!OCSP_resp_find_status(bs, cinf->cid, &status, &reason, &rev,
+ &thisupd, &nextupd)) {
+ /* If ID not present just pass back to client */
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01935)
+ "stapling_check_response: certificate ID not present in response!");
+ }
+ else {
+ if (OCSP_check_validity(thisupd, nextupd,
+ mctx->stapling_resptime_skew,
+ mctx->stapling_resp_maxage)) {
+ if (pok)
+ *pok = TRUE;
+ }
+ else {
+ /* If pok is not NULL response was direct from a responder and
+ * the times should be valide. If pok is NULL the response was
+ * retrieved from cache and it is expected to subsequently expire
+ */
+ if (pok) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01936)
+ "stapling_check_response: response times invalid");
+ }
+ else {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01937)
+ "stapling_check_response: cached response expired");
+ }
+
+ OCSP_BASICRESP_free(bs);
+ return SSL_TLSEXT_ERR_NOACK;
+ }
+ }
+
+ OCSP_BASICRESP_free(bs);
+
+ return SSL_TLSEXT_ERR_OK;
+}
+
+static BOOL stapling_renew_response(server_rec *s, modssl_ctx_t *mctx, SSL *ssl,
+ certinfo *cinf, OCSP_RESPONSE **prsp,
+ apr_pool_t *pool)
+{
+ conn_rec *conn = (conn_rec *)SSL_get_app_data(ssl);
+ apr_pool_t *vpool;
+ OCSP_REQUEST *req = NULL;
+ OCSP_CERTID *id = NULL;
+ STACK_OF(X509_EXTENSION) *exts;
+ int i;
+ BOOL ok = FALSE;
+ BOOL rv = TRUE;
+ const char *ocspuri;
+ apr_uri_t uri;
+
+ *prsp = NULL;
+ /* Build up OCSP query from server certificate info */
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01938)
+ "stapling_renew_response: querying responder");
+
+ req = OCSP_REQUEST_new();
+ if (!req)
+ goto err;
+ id = OCSP_CERTID_dup(cinf->cid);
+ if (!id)
+ goto err;
+ if (!OCSP_request_add0_id(req, id))
+ goto err;
+ id = NULL;
+ /* Add any extensions to the request */
+ SSL_get_tlsext_status_exts(ssl, &exts);
+ for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
+ X509_EXTENSION *ext = sk_X509_EXTENSION_value(exts, i);
+ if (!OCSP_REQUEST_add_ext(req, ext, -1))
+ goto err;
+ }
+
+ if (mctx->stapling_force_url)
+ ocspuri = mctx->stapling_force_url;
+ else
+ ocspuri = cinf->uri;
+
+ /* Create a temporary pool to constrain memory use */
+ apr_pool_create(&vpool, conn->pool);
+
+ ok = apr_uri_parse(vpool, ocspuri, &uri);
+ if (ok != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01939)
+ "stapling_renew_response: Error parsing uri %s",
+ ocspuri);
+ rv = FALSE;
+ goto done;
+ }
+ else if (strcmp(uri.scheme, "http")) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01940)
+ "stapling_renew_response: Unsupported uri %s", ocspuri);
+ rv = FALSE;
+ goto done;
+ }
+
+ if (!uri.port) {
+ uri.port = apr_uri_port_of_scheme(uri.scheme);
+ }
+
+ *prsp = modssl_dispatch_ocsp_request(&uri, mctx->stapling_responder_timeout,
+ req, conn, vpool);
+
+ apr_pool_destroy(vpool);
+
+ if (!*prsp) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01941)
+ "stapling_renew_response: responder error");
+ if (mctx->stapling_fake_trylater) {
+ *prsp = OCSP_response_create(OCSP_RESPONSE_STATUS_TRYLATER, NULL);
+ }
+ else {
+ goto done;
+ }
+ }
+ else {
+ int response_status = OCSP_response_status(*prsp);
+
+ if (response_status == OCSP_RESPONSE_STATUS_SUCCESSFUL) {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01942)
+ "stapling_renew_response: query response received");
+ stapling_check_response(s, mctx, cinf, *prsp, &ok);
+ if (ok == FALSE) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01943)
+ "stapling_renew_response: error in retreived response!");
+ }
+ }
+ else {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01944)
+ "stapling_renew_response: responder error %s",
+ OCSP_response_status_str(response_status));
+ }
+ }
+ if (stapling_cache_response(s, mctx, *prsp, cinf, ok, pool) == FALSE) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01945)
+ "stapling_renew_response: error caching response!");
+ }
+
+done:
+ if (id)
+ OCSP_CERTID_free(id);
+ if (req)
+ OCSP_REQUEST_free(req);
+ return rv;
+err:
+ rv = FALSE;
+ goto done;
+}
+
+/*
+ * SSLStaplingMutex operations. Similar to SSL mutex except a mutex is
+ * mandatory if stapling is enabled.
+ */
+static int ssl_stapling_mutex_init(server_rec *s, apr_pool_t *p)
+{
+ SSLModConfigRec *mc = myModConfig(s);
+ SSLSrvConfigRec *sc = mySrvConfig(s);
+ apr_status_t rv;
+
+ if (mc->stapling_mutex || sc->server->stapling_enabled != TRUE) {
+ return TRUE;
+ }
+
+ if ((rv = ap_global_mutex_create(&mc->stapling_mutex, NULL,
+ SSL_STAPLING_MUTEX_TYPE, NULL, s,
+ s->process->pool, 0)) != APR_SUCCESS) {
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+int ssl_stapling_mutex_reinit(server_rec *s, apr_pool_t *p)
+{
+ SSLModConfigRec *mc = myModConfig(s);
+ apr_status_t rv;
+ const char *lockfile;
+
+ if (mc->stapling_mutex == NULL) {
+ return TRUE;
+ }
+
+ lockfile = apr_global_mutex_lockfile(mc->stapling_mutex);
+ if ((rv = apr_global_mutex_child_init(&mc->stapling_mutex,
+ lockfile, p)) != APR_SUCCESS) {
+ if (lockfile) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, rv, s, APLOGNO(01946)
+ "Cannot reinit %s mutex with file `%s'",
+ SSL_STAPLING_MUTEX_TYPE, lockfile);
+ }
+ else {
+ ap_log_error(APLOG_MARK, APLOG_WARNING, rv, s, APLOGNO(01947)
+ "Cannot reinit %s mutex", SSL_STAPLING_MUTEX_TYPE);
+ }
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static int stapling_mutex_on(server_rec *s)
+{
+ SSLModConfigRec *mc = myModConfig(s);
+ apr_status_t rv;
+
+ if ((rv = apr_global_mutex_lock(mc->stapling_mutex)) != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_WARNING, rv, s, APLOGNO(01948)
+ "Failed to acquire OCSP stapling lock");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static int stapling_mutex_off(server_rec *s)
+{
+ SSLModConfigRec *mc = myModConfig(s);
+ apr_status_t rv;
+
+ if ((rv = apr_global_mutex_unlock(mc->stapling_mutex)) != APR_SUCCESS) {
+ ap_log_error(APLOG_MARK, APLOG_WARNING, rv, s, APLOGNO(01949)
+ "Failed to release OCSP stapling lock");
+ return FALSE;
+ }
+ return TRUE;
+}
+
+/* Certificate Status callback. This is called when a client includes a
+ * certificate status request extension.
+ *
+ * Check for cached responses in session cache. If valid send back to
+ * client. If absent or no longer valid query responder and update
+ * cache. */
+static int stapling_cb(SSL *ssl, void *arg)
+{
+ conn_rec *conn = (conn_rec *)SSL_get_app_data(ssl);
+ server_rec *s = mySrvFromConn(conn);
+ SSLSrvConfigRec *sc = mySrvConfig(s);
+ SSLConnRec *sslconn = myConnConfig(conn);
+ modssl_ctx_t *mctx = myCtxConfig(sslconn, sc);
+ certinfo *cinf = NULL;
+ OCSP_RESPONSE *rsp = NULL;
+ int rv;
+ BOOL ok;
+
+ if (sc->server->stapling_enabled != TRUE) {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01950)
+ "stapling_cb: OCSP Stapling disabled");
+ return SSL_TLSEXT_ERR_NOACK;
+ }
+
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01951)
+ "stapling_cb: OCSP Stapling callback called");
+
+ cinf = stapling_get_cert_info(s, mctx, ssl);
+ if (cinf == NULL) {
+ return SSL_TLSEXT_ERR_NOACK;
+ }
+
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01952)
+ "stapling_cb: retrieved cached certificate data");
+
+ /* Check to see if we already have a response for this certificate */
+ stapling_mutex_on(s);
+
+ rv = stapling_get_cached_response(s, &rsp, &ok, cinf, conn->pool);
+ if (rv == FALSE) {
+ stapling_mutex_off(s);
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
+ }
+
+ if (rsp) {
+ /* see if response is acceptable */
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01953)
+ "stapling_cb: retrieved cached response");
+ rv = stapling_check_response(s, mctx, cinf, rsp, NULL);
+ if (rv == SSL_TLSEXT_ERR_ALERT_FATAL) {
+ OCSP_RESPONSE_free(rsp);
+ stapling_mutex_off(s);
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
+ }
+ else if (rv == SSL_TLSEXT_ERR_NOACK) {
+ /* Error in response. If this error was not present when it was
+ * stored (i.e. response no longer valid) then it can be
+ * renewed straight away.
+ *
+ * If the error *was* present at the time it was stored then we
+ * don't renew the response straight away we just wait for the
+ * cached response to expire.
+ */
+ if (ok) {
+ OCSP_RESPONSE_free(rsp);
+ rsp = NULL;
+ }
+ else if (!mctx->stapling_return_errors) {
+ OCSP_RESPONSE_free(rsp);
+ stapling_mutex_off(s);
+ return SSL_TLSEXT_ERR_NOACK;
+ }
+ }
+ }
+
+ if (rsp == NULL) {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01954)
+ "stapling_cb: renewing cached response");
+ rv = stapling_renew_response(s, mctx, ssl, cinf, &rsp, conn->pool);
+
+ if (rv == FALSE) {
+ stapling_mutex_off(s);
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01955)
+ "stapling_cb: fatal error");
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
+ }
+ }
+ stapling_mutex_off(s);
+
+ if (rsp) {
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01956)
+ "stapling_cb: setting response");
+ if (!stapling_set_response(ssl, rsp))
+ return SSL_TLSEXT_ERR_ALERT_FATAL;
+ return SSL_TLSEXT_ERR_OK;
+ }
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01957)
+ "stapling_cb: no response available");
+
+ return SSL_TLSEXT_ERR_NOACK;
+
+}
+
+void modssl_init_stapling(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp,
+ modssl_ctx_t *mctx)
+{
+ SSL_CTX *ctx = mctx->ssl_ctx;
+ SSLModConfigRec *mc = myModConfig(s);
+
+ if (mc->stapling_cache == NULL) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01958)
+ "SSLStapling: no stapling cache available");
+ ssl_die();
+ }
+ if (ssl_stapling_mutex_init(s, ptemp) == FALSE) {
+ ap_log_error(APLOG_MARK, APLOG_EMERG, 0, s, APLOGNO(01959)
+ "SSLStapling: cannot initialise stapling mutex");
+ ssl_die();
+ }
+ /* Set some default values for parameters if they are not set */
+ if (mctx->stapling_resptime_skew == UNSET) {
+ mctx->stapling_resptime_skew = 60 * 5;
+ }
+ if (mctx->stapling_cache_timeout == UNSET) {
+ mctx->stapling_cache_timeout = 3600;
+ }
+ if (mctx->stapling_return_errors == UNSET) {
+ mctx->stapling_return_errors = TRUE;
+ }
+ if (mctx->stapling_fake_trylater == UNSET) {
+ mctx->stapling_fake_trylater = TRUE;
+ }
+ if (mctx->stapling_errcache_timeout == UNSET) {
+ mctx->stapling_errcache_timeout = 600;
+ }
+ if (mctx->stapling_responder_timeout == UNSET) {
+ mctx->stapling_responder_timeout = 10 * APR_USEC_PER_SEC;
+ }
+ SSL_CTX_set_tlsext_status_cb(ctx, stapling_cb);
+ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01960) "OCSP stapling initialized");
+}
+
+#endif