mirror of
https://github.com/apache/httpd.git
synced 2025-08-08 15:02:10 +03:00
Add Configuration for trusted OCSP responder certificates
Fix for PR 46037 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1781575 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
130
build/PrintPath
130
build/PrintPath
@@ -1,130 +0,0 @@
|
|||||||
#!/bin/sh
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# Look for program[s] somewhere in $PATH.
|
|
||||||
#
|
|
||||||
# Options:
|
|
||||||
# -s
|
|
||||||
# Do not print out full pathname. (silent)
|
|
||||||
# -pPATHNAME
|
|
||||||
# Look in PATHNAME instead of $PATH
|
|
||||||
#
|
|
||||||
# Usage:
|
|
||||||
# PrintPath [-s] [-pPATHNAME] program [program ...]
|
|
||||||
#
|
|
||||||
# Initially written by Jim Jagielski for the Apache configuration mechanism
|
|
||||||
# (with kudos to Kernighan/Pike)
|
|
||||||
|
|
||||||
##
|
|
||||||
# Some "constants"
|
|
||||||
##
|
|
||||||
pathname=$PATH
|
|
||||||
echo="yes"
|
|
||||||
|
|
||||||
##
|
|
||||||
# Find out what OS we are running for later on
|
|
||||||
##
|
|
||||||
os=`(uname) 2>/dev/null`
|
|
||||||
|
|
||||||
##
|
|
||||||
# Parse command line
|
|
||||||
##
|
|
||||||
for args in $*
|
|
||||||
do
|
|
||||||
case $args in
|
|
||||||
-s ) echo="no" ;;
|
|
||||||
-p* ) pathname="`echo $args | sed 's/^..//'`" ;;
|
|
||||||
* ) programs="$programs $args" ;;
|
|
||||||
esac
|
|
||||||
done
|
|
||||||
|
|
||||||
##
|
|
||||||
# Now we make the adjustments required for OS/2 and everyone
|
|
||||||
# else :)
|
|
||||||
#
|
|
||||||
# First of all, all OS/2 programs have the '.exe' extension.
|
|
||||||
# Next, we adjust PATH (or what was given to us as PATH) to
|
|
||||||
# be whitespace separated directories.
|
|
||||||
# Finally, we try to determine the best flag to use for
|
|
||||||
# test/[] to look for an executable file. OS/2 just has '-r'
|
|
||||||
# but with other OSs, we do some funny stuff to check to see
|
|
||||||
# if test/[] knows about -x, which is the prefered flag.
|
|
||||||
##
|
|
||||||
|
|
||||||
if [ "x$os" = "xOS/2" ]
|
|
||||||
then
|
|
||||||
ext=".exe"
|
|
||||||
pathname=`echo -E $pathname |
|
|
||||||
sed 's/^;/.;/
|
|
||||||
s/;;/;.;/g
|
|
||||||
s/;$/;./
|
|
||||||
s/;/ /g
|
|
||||||
s/\\\\/\\//g' `
|
|
||||||
test_exec_flag="-r"
|
|
||||||
else
|
|
||||||
ext="" # No default extensions
|
|
||||||
pathname=`echo $pathname |
|
|
||||||
sed 's/^:/.:/
|
|
||||||
s/::/:.:/g
|
|
||||||
s/:$/:./
|
|
||||||
s/:/ /g' `
|
|
||||||
# Here is how we test to see if test/[] can handle -x
|
|
||||||
testfile="pp.t.$$"
|
|
||||||
|
|
||||||
cat > $testfile <<ENDTEST
|
|
||||||
#!/bin/sh
|
|
||||||
if [ -x / ] || [ -x /bin ] || [ -x /bin/ls ]; then
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
exit 1
|
|
||||||
ENDTEST
|
|
||||||
|
|
||||||
if `/bin/sh $testfile 2>/dev/null`; then
|
|
||||||
test_exec_flag="-x"
|
|
||||||
else
|
|
||||||
test_exec_flag="-r"
|
|
||||||
fi
|
|
||||||
rm -f $testfile
|
|
||||||
fi
|
|
||||||
|
|
||||||
for program in $programs
|
|
||||||
do
|
|
||||||
for path in $pathname
|
|
||||||
do
|
|
||||||
if [ $test_exec_flag $path/${program}${ext} ] && \
|
|
||||||
[ ! -d $path/${program}${ext} ]; then
|
|
||||||
if [ "x$echo" = "xyes" ]; then
|
|
||||||
echo $path/${program}${ext}
|
|
||||||
fi
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
|
|
||||||
# Next try without extension (if one was used above)
|
|
||||||
if [ "x$ext" != "x" ]; then
|
|
||||||
if [ $test_exec_flag $path/${program} ] && \
|
|
||||||
[ ! -d $path/${program} ]; then
|
|
||||||
if [ "x$echo" = "xyes" ]; then
|
|
||||||
echo $path/${program}
|
|
||||||
fi
|
|
||||||
exit 0
|
|
||||||
fi
|
|
||||||
fi
|
|
||||||
done
|
|
||||||
done
|
|
||||||
exit 1
|
|
||||||
|
|
@@ -264,6 +264,14 @@ static const command_rec ssl_config_cmds[] = {
|
|||||||
SSL_CMD_SRV(OCSPProxyURL, TAKE1,
|
SSL_CMD_SRV(OCSPProxyURL, TAKE1,
|
||||||
"Proxy URL to use for OCSP requests")
|
"Proxy URL to use for OCSP requests")
|
||||||
|
|
||||||
|
/* Define OCSP Responder Certificate Verification Directive */
|
||||||
|
SSL_CMD_SRV(OCSPNoverify, FLAG,
|
||||||
|
"Do not verify OCSP Responder certificate ('on', 'off')")
|
||||||
|
/* Define OCSP Responder File Configuration Directive */
|
||||||
|
SSL_CMD_SRV(OCSPResponderCertificateFile, TAKE1,
|
||||||
|
"Trusted OCSP responder certificates"
|
||||||
|
"(`/path/to/file' - PEM encoded certificates)")
|
||||||
|
|
||||||
#ifdef HAVE_OCSP_STAPLING
|
#ifdef HAVE_OCSP_STAPLING
|
||||||
/*
|
/*
|
||||||
* OCSP Stapling options
|
* OCSP Stapling options
|
||||||
|
@@ -146,6 +146,13 @@ static void modssl_ctx_init(modssl_ctx_t *mctx, apr_pool_t *p)
|
|||||||
mctx->ocsp_use_request_nonce = UNSET;
|
mctx->ocsp_use_request_nonce = UNSET;
|
||||||
mctx->proxy_uri = NULL;
|
mctx->proxy_uri = NULL;
|
||||||
|
|
||||||
|
/* Set OCSP Responder Certificate Verification variable */
|
||||||
|
mctx->ocsp_noverify = FALSE;
|
||||||
|
/* Set OCSP Responder File variables */
|
||||||
|
mctx->ocsp_verify_flags = 0;
|
||||||
|
mctx->ocsp_certs_file = NULL;
|
||||||
|
mctx->ocsp_certs = NULL;
|
||||||
|
|
||||||
#ifdef HAVE_OCSP_STAPLING
|
#ifdef HAVE_OCSP_STAPLING
|
||||||
mctx->stapling_enabled = UNSET;
|
mctx->stapling_enabled = UNSET;
|
||||||
mctx->stapling_resptime_skew = UNSET;
|
mctx->stapling_resptime_skew = UNSET;
|
||||||
@@ -282,6 +289,12 @@ static void modssl_ctx_cfg_merge(apr_pool_t *p,
|
|||||||
cfgMergeInt(ocsp_responder_timeout);
|
cfgMergeInt(ocsp_responder_timeout);
|
||||||
cfgMergeBool(ocsp_use_request_nonce);
|
cfgMergeBool(ocsp_use_request_nonce);
|
||||||
cfgMerge(proxy_uri, NULL);
|
cfgMerge(proxy_uri, NULL);
|
||||||
|
|
||||||
|
/* Set OCSP Responder Certificate Verification directive */
|
||||||
|
cfgMergeBool(ocsp_noverify);
|
||||||
|
/* Set OCSP Responder File directive for importing */
|
||||||
|
cfgMerge(ocsp_certs_file, NULL);
|
||||||
|
|
||||||
#ifdef HAVE_OCSP_STAPLING
|
#ifdef HAVE_OCSP_STAPLING
|
||||||
cfgMergeBool(stapling_enabled);
|
cfgMergeBool(stapling_enabled);
|
||||||
cfgMergeInt(stapling_resptime_skew);
|
cfgMergeInt(stapling_resptime_skew);
|
||||||
@@ -1707,6 +1720,16 @@ const char *ssl_cmd_SSLOCSPProxyURL(cmd_parms *cmd, void *dcfg,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Set OCSP responder certificate verification directive */
|
||||||
|
const char *ssl_cmd_SSLOCSPNoverify(cmd_parms *cmd, void *dcfg, int flag)
|
||||||
|
{
|
||||||
|
SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
|
||||||
|
|
||||||
|
sc->server->ocsp_noverify = flag ? TRUE : FALSE;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
const char *ssl_cmd_SSLProxyCheckPeerExpire(cmd_parms *cmd, void *dcfg, int flag)
|
const char *ssl_cmd_SSLProxyCheckPeerExpire(cmd_parms *cmd, void *dcfg, int flag)
|
||||||
{
|
{
|
||||||
SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
|
SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
|
||||||
@@ -1958,6 +1981,21 @@ const char *ssl_cmd_SSLSRPUnknownUserSeed(cmd_parms *cmd, void *dcfg,
|
|||||||
|
|
||||||
#endif /* HAVE_SRP */
|
#endif /* HAVE_SRP */
|
||||||
|
|
||||||
|
/* OCSP Responder File Function to read in value */
|
||||||
|
const char *ssl_cmd_SSLOCSPResponderCertificateFile(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->ocsp_certs_file = arg;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s)
|
void ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s)
|
||||||
{
|
{
|
||||||
apr_file_t *out = NULL;
|
apr_file_t *out = NULL;
|
||||||
|
@@ -1762,6 +1762,12 @@ apr_status_t ssl_init_ConfigureServer(server_rec *s,
|
|||||||
!= APR_SUCCESS) {
|
!= APR_SUCCESS) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialize OCSP Responder certificate if OCSP enabled */
|
||||||
|
#ifndef OPENSSL_NO_OCSP
|
||||||
|
ssl_init_ocsp_certificates(s, sc->server);
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sdc->proxy->sc = sc;
|
sdc->proxy->sc = sc;
|
||||||
@@ -2061,6 +2067,12 @@ apr_status_t ssl_init_ModuleKill(void *data)
|
|||||||
sc = mySrvConfig(s);
|
sc = mySrvConfig(s);
|
||||||
|
|
||||||
ssl_init_ctx_cleanup(sc->server);
|
ssl_init_ctx_cleanup(sc->server);
|
||||||
|
|
||||||
|
/* Not Sure but possibly clear X509 trusted cert file */
|
||||||
|
#ifndef OPENSSL_NO_OCSP
|
||||||
|
sk_X509_pop_free(sc->server->ocsp_certs, X509_free);
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||||
|
@@ -183,14 +183,18 @@ static int verify_ocsp_status(X509 *cert, X509_STORE_CTX *ctx, conn_rec *c,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rc == V_OCSP_CERTSTATUS_GOOD) {
|
if (rc == V_OCSP_CERTSTATUS_GOOD) {
|
||||||
/* TODO: allow flags configuration. */
|
/* Check if OCSP certificate verification required */
|
||||||
if (OCSP_basic_verify(basicResponse, NULL, X509_STORE_CTX_get0_store(ctx), 0) != 1) {
|
if (!sc->server->ocsp_noverify) {
|
||||||
|
/* Modify OCSP response verification to include OCSP Responder cert */
|
||||||
|
if (OCSP_basic_verify(basicResponse, sc->server->ocsp_certs, X509_STORE_CTX_get0_store(ctx),
|
||||||
|
sc->server->ocsp_verify_flags) != 1) {
|
||||||
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01925)
|
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01925)
|
||||||
"failed to verify the OCSP response");
|
"failed to verify the OCSP response");
|
||||||
ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s);
|
ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s);
|
||||||
rc = V_OCSP_CERTSTATUS_UNKNOWN;
|
rc = V_OCSP_CERTSTATUS_UNKNOWN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (rc == V_OCSP_CERTSTATUS_GOOD) {
|
if (rc == V_OCSP_CERTSTATUS_GOOD) {
|
||||||
int reason = -1, status;
|
int reason = -1, status;
|
||||||
|
@@ -678,6 +678,12 @@ typedef struct {
|
|||||||
BOOL ocsp_use_request_nonce;
|
BOOL ocsp_use_request_nonce;
|
||||||
apr_uri_t *proxy_uri;
|
apr_uri_t *proxy_uri;
|
||||||
|
|
||||||
|
BOOL ocsp_noverify; /* true if skipping OCSP certification verification like openssl -noverify */
|
||||||
|
/* Declare variables for using OCSP Responder Certs for OCSP verification */
|
||||||
|
int ocsp_verify_flags; /* Flags to use when verifying OCSP response */
|
||||||
|
const char *ocsp_certs_file; /* OCSP other certificates filename */
|
||||||
|
STACK_OF(X509) *ocsp_certs; /* OCSP other certificates */
|
||||||
|
|
||||||
#ifdef HAVE_SSL_CONF_CMD
|
#ifdef HAVE_SSL_CONF_CMD
|
||||||
SSL_CONF_CTX *ssl_ctx_config; /* Configuration context */
|
SSL_CONF_CTX *ssl_ctx_config; /* Configuration context */
|
||||||
apr_array_header_t *ssl_ctx_param; /* parameters to pass to SSL_CTX */
|
apr_array_header_t *ssl_ctx_param; /* parameters to pass to SSL_CTX */
|
||||||
@@ -808,6 +814,11 @@ const char *ssl_cmd_SSLOCSPUseRequestNonce(cmd_parms *cmd, void *dcfg, int flag)
|
|||||||
const char *ssl_cmd_SSLOCSPEnable(cmd_parms *cmd, void *dcfg, int flag);
|
const char *ssl_cmd_SSLOCSPEnable(cmd_parms *cmd, void *dcfg, int flag);
|
||||||
const char *ssl_cmd_SSLOCSPProxyURL(cmd_parms *cmd, void *dcfg, const char *arg);
|
const char *ssl_cmd_SSLOCSPProxyURL(cmd_parms *cmd, void *dcfg, const char *arg);
|
||||||
|
|
||||||
|
/* Declare OCSP Responder Certificate Verification Directive */
|
||||||
|
const char *ssl_cmd_SSLOCSPNoverify(cmd_parms *cmd, void *dcfg, int flag);
|
||||||
|
/* Declare OCSP Responder Certificate File Directive */
|
||||||
|
const char *ssl_cmd_SSLOCSPResponderCertificateFile(cmd_parms *cmd, void *dcfg, const char *arg);
|
||||||
|
|
||||||
#ifdef HAVE_SSL_CONF_CMD
|
#ifdef HAVE_SSL_CONF_CMD
|
||||||
const char *ssl_cmd_SSLOpenSSLConfCmd(cmd_parms *cmd, void *dcfg, const char *arg1, const char *arg2);
|
const char *ssl_cmd_SSLOpenSSLConfCmd(cmd_parms *cmd, void *dcfg, const char *arg1, const char *arg2);
|
||||||
#endif
|
#endif
|
||||||
@@ -1022,6 +1033,10 @@ OCSP_RESPONSE *modssl_dispatch_ocsp_request(const apr_uri_t *uri,
|
|||||||
apr_interval_time_t timeout,
|
apr_interval_time_t timeout,
|
||||||
OCSP_REQUEST *request,
|
OCSP_REQUEST *request,
|
||||||
conn_rec *c, apr_pool_t *p);
|
conn_rec *c, apr_pool_t *p);
|
||||||
|
|
||||||
|
/* Initialize OCSP trusted certificate list */
|
||||||
|
void ssl_init_ocsp_certificates(server_rec *s, modssl_ctx_t *mctx);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Retrieve DH parameters for given key length. Return value should
|
/* Retrieve DH parameters for given key length. Return value should
|
||||||
|
@@ -339,4 +339,82 @@ OCSP_RESPONSE *modssl_dispatch_ocsp_request(const apr_uri_t *uri,
|
|||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* _________________________________________________________________
|
||||||
|
**
|
||||||
|
** OCSP other certificate support
|
||||||
|
** _________________________________________________________________
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Read a file that contains certificates in PEM format and
|
||||||
|
* return as a STACK.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static STACK_OF(X509) *modssl_read_ocsp_certificates(const char *file)
|
||||||
|
{
|
||||||
|
BIO *bio;
|
||||||
|
X509 *x509;
|
||||||
|
unsigned long err;
|
||||||
|
int n;
|
||||||
|
STACK_OF(X509) *other_certs = NULL;
|
||||||
|
|
||||||
|
if ((bio = BIO_new(BIO_s_file_internal())) == NULL)
|
||||||
|
return NULL;
|
||||||
|
if (BIO_read_filename(bio, file) <= 0) {
|
||||||
|
BIO_free(bio);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
/* create new extra chain by loading the certs */
|
||||||
|
while ((x509 = PEM_read_bio_X509(bio, NULL, NULL, NULL)) != NULL) {
|
||||||
|
if (!other_certs) {
|
||||||
|
other_certs = sk_X509_new_null();
|
||||||
|
if (!other_certs)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!sk_X509_push(other_certs, x509)) {
|
||||||
|
X509_free(x509);
|
||||||
|
sk_X509_pop_free(other_certs, X509_free);
|
||||||
|
BIO_free(bio);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Make sure that only the error is just an EOF */
|
||||||
|
if ((err = ERR_peek_error()) > 0) {
|
||||||
|
if (!( ERR_GET_LIB(err) == ERR_LIB_PEM
|
||||||
|
&& ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
|
||||||
|
BIO_free(bio);
|
||||||
|
sk_X509_pop_free(other_certs, X509_free);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
while (ERR_get_error() > 0) ;
|
||||||
|
}
|
||||||
|
BIO_free(bio);
|
||||||
|
return other_certs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ssl_init_ocsp_certificates(server_rec *s, modssl_ctx_t *mctx)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Configure Trusted OCSP certificates.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!mctx->ocsp_certs_file) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
|
||||||
|
"Configuring Trusted OCSP certificates");
|
||||||
|
|
||||||
|
mctx->ocsp_certs = modssl_read_ocsp_certificates(mctx->ocsp_certs_file);
|
||||||
|
|
||||||
|
if (!mctx->ocsp_certs) {
|
||||||
|
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
|
||||||
|
"Unable to configure OCSP Trusted Certificates");
|
||||||
|
ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, s);
|
||||||
|
ssl_die(s);
|
||||||
|
}
|
||||||
|
mctx->ocsp_verify_flags |= OCSP_TRUSTOTHER;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* HAVE_OCSP */
|
#endif /* HAVE_OCSP */
|
||||||
|
Reference in New Issue
Block a user