summaryrefslogtreecommitdiff
path: root/modules/ssl/ssl_engine_init.c
diff options
context:
space:
mode:
author(no author) <(no author)@unknown>2001-05-04 21:54:25 +0000
committer(no author) <(no author)@unknown>2001-05-04 21:54:25 +0000
commitad2dd84025f628d29200b5a9a41d654be678aa6f (patch)
tree35a838b6e9d6510a91e386728e78b4a81cb55781 /modules/ssl/ssl_engine_init.c
parentf83672781de25207442ff908258219de1d103062 (diff)
downloadhttpd-RSE.tar.gz
This commit was manufactured by cvs2svn to create branch 'RSE'.RSE
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/RSE@88989 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'modules/ssl/ssl_engine_init.c')
-rw-r--r--modules/ssl/ssl_engine_init.c1090
1 files changed, 0 insertions, 1090 deletions
diff --git a/modules/ssl/ssl_engine_init.c b/modules/ssl/ssl_engine_init.c
deleted file mode 100644
index 6a27c4af4d..0000000000
--- a/modules/ssl/ssl_engine_init.c
+++ /dev/null
@@ -1,1090 +0,0 @@
-/* _ _
-** _ __ ___ ___ __| | ___ ___| | mod_ssl
-** | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL
-** | | | | | | (_) | (_| | \__ \__ \ | www.modssl.org
-** |_| |_| |_|\___/ \__,_|___|___/___/_| ftp.modssl.org
-** |_____|
-** ssl_engine_init.c
-** Initialization of Servers
-*/
-
-/* ====================================================================
- * Copyright (c) 1998-2001 Ralf S. Engelschall. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following
- * disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by
- * Ralf S. Engelschall <rse@engelschall.com> for use in the
- * mod_ssl project (http://www.modssl.org/)."
- *
- * 4. The names "mod_ssl" must not be used to endorse or promote
- * products derived from this software without prior written
- * permission. For written permission, please contact
- * rse@engelschall.com.
- *
- * 5. Products derived from this software may not be called "mod_ssl"
- * nor may "mod_ssl" appear in their names without prior
- * written permission of Ralf S. Engelschall.
- *
- * 6. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by
- * Ralf S. Engelschall <rse@engelschall.com> for use in the
- * mod_ssl project (http://www.modssl.org/)."
- *
- * THIS SOFTWARE IS PROVIDED BY RALF S. ENGELSCHALL ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RALF S. ENGELSCHALL OR
- * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- */
-
-/* ====================================================================
- * Copyright (c) 1995-1999 Ben Laurie. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. All advertising materials mentioning features or use of this
- * software must display the following acknowledgment:
- * "This product includes software developed by Ben Laurie
- * for use in the Apache-SSL HTTP server project."
- *
- * 4. The name "Apache-SSL Server" must not be used to
- * endorse or promote products derived from this software without
- * prior written permission.
- *
- * 5. Redistributions of any form whatsoever must retain the following
- * acknowledgment:
- * "This product includes software developed by Ben Laurie
- * for use in the Apache-SSL HTTP server project."
- *
- * THIS SOFTWARE IS PROVIDED BY BEN LAURIE ``AS IS'' AND ANY
- * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BEN LAURIE OR
- * HIS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- * ====================================================================
- */
- /* ``Recursive, adj.;
- see Recursive.''
- -- Unknown */
-#include "mod_ssl.h"
-
-
-/* _________________________________________________________________
-**
-** Module Initialization
-** _________________________________________________________________
-*/
-
-/*
- * Per-module initialization
- */
-void ssl_init_Module(server_rec *s, pool *p)
-{
- SSLModConfigRec *mc = myModConfig();
- SSLSrvConfigRec *sc;
- server_rec *s2;
- char *cp;
-
- mc->nInitCount++;
-
- /*
- * Let us cleanup on restarts and exists
- */
- ap_register_cleanup(p, s, ssl_init_ModuleKill, ssl_init_ChildKill);
-
- /*
- * Any init round fixes the global config
- */
- ssl_config_global_create(); /* just to avoid problems */
- ssl_config_global_fix();
-
- /*
- * try to fix the configuration and open the dedicated SSL
- * logfile as early as possible
- */
- for (s2 = s; s2 != NULL; s2 = s2->next) {
- sc = mySrvConfig(s2);
-
- /* Fix up stuff that may not have been set */
- if (sc->bEnabled == UNSET)
- sc->bEnabled = FALSE;
- if (sc->nVerifyClient == SSL_CVERIFY_UNSET)
- sc->nVerifyClient = SSL_CVERIFY_NONE;
- if (sc->nVerifyDepth == UNSET)
- sc->nVerifyDepth = 1;
-#ifdef SSL_EXPERIMENTAL_PROXY
- if (sc->nProxyVerifyDepth == UNSET)
- sc->nProxyVerifyDepth = 1;
-#endif
- if (sc->nSessionCacheTimeout == UNSET)
- sc->nSessionCacheTimeout = SSL_SESSION_CACHE_TIMEOUT;
- if (sc->nPassPhraseDialogType == SSL_PPTYPE_UNSET)
- sc->nPassPhraseDialogType = SSL_PPTYPE_BUILTIN;
-
- /* Open the dedicated SSL logfile */
- ssl_log_open(s, s2, p);
- }
-
- /*
- * Identification
- */
- if (mc->nInitCount == 1) {
- ssl_log(s, SSL_LOG_INFO, "Server: %s, Interface: %s, Library: %s",
- SERVER_BASEVERSION,
- ssl_var_lookup(p, NULL, NULL, NULL, "SSL_VERSION_INTERFACE"),
- ssl_var_lookup(p, NULL, NULL, NULL, "SSL_VERSION_LIBRARY"));
-#ifdef WIN32
- ssl_log(s, SSL_LOG_WARN, "You are using mod_ssl under Win32. "
- "This combination is *NOT* officially supported. "
- "Use it at your own risk!");
-#endif
- }
-
- /*
- * Initialization round information
- */
- if (mc->nInitCount == 1)
- ssl_log(s, SSL_LOG_INFO, "Init: 1st startup round (still not detached)");
- else if (mc->nInitCount == 2)
- ssl_log(s, SSL_LOG_INFO, "Init: 2nd startup round (already detached)");
- else
- ssl_log(s, SSL_LOG_INFO, "Init: %d%s restart round (already detached)",
- mc->nInitCount-2, (mc->nInitCount-2) == 1 ? "st" : "nd");
-
-#ifdef SSL_VENDOR
- ap_hook_use("ap::mod_ssl::vendor::init_module",
- AP_HOOK_SIG3(void,ptr,ptr), AP_HOOK_ALL, s, p);
-#endif
-
- /*
- * The initialization phase inside the Apache API is totally bogus.
- * We actually have three non-trivial problems:
- *
- * 1. Under Unix the API does a 2-round initialization of modules while
- * under Win32 it doesn't. This means we have to make sure that at
- * least the pass phrase dialog doesn't occur twice. We overcome this
- * problem by using a counter (mc->nInitCount) which has to
- * survive the init rounds.
- *
- * 2. Between the first and the second round Apache detaches from
- * the terminal under Unix. This means that our pass phrase dialog
- * _has_ to be done in the first round and _cannot_ be done in the
- * second round.
- *
- * 3. When Dynamic Shared Object (DSO) mechanism is used under Unix the
- * module segment (code & data) gets unloaded and re-loaded between
- * the first and the second round. This means no global data survives
- * between first and the second init round. We overcome this by using
- * an entry ("ssl_module") inside the ap_global_ctx.
- *
- * The situation as a table:
- *
- * Unix/static Unix/DSO Win32 Action Required
- * (-DSHARED_MODULE) (-DWIN32)
- * ----------- ----------------- --------- -----------------------------------
- * - load module - -
- * init init init SSL library init, Pass Phrase Dialog
- * detach detach - -
- * - reload module - -
- * init init - SSL library init, mod_ssl init
- *
- * Ok, now try to solve this totally ugly situation...
- */
-
-#ifdef SHARED_MODULE
- ssl_log(s, SSL_LOG_INFO, "Init: %snitializing %s library",
- mc->nInitCount == 1 ? "I" : "Rei", SSL_LIBRARY_NAME);
- ssl_init_SSLLibrary();
-#else
- if (mc->nInitCount <= 2) {
- ssl_log(s, SSL_LOG_INFO, "Init: %snitializing %s library",
- mc->nInitCount == 1 ? "I" : "Rei", SSL_LIBRARY_NAME);
- ssl_init_SSLLibrary();
- }
-#endif
- if (mc->nInitCount == 1) {
- ssl_pphrase_Handle(s, p);
- ssl_init_TmpKeysHandle(SSL_TKP_GEN, s, p);
-#ifndef WIN32
- return;
-#endif
- }
-
- /*
- * SSL external crypto device ("engine") support
- */
-#ifdef SSL_EXPERIMENTAL_ENGINE
- ssl_init_Engine(s, p);
-#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) {
- ssl_log(s, SSL_LOG_WARN,
- "Init: Session Cache is not configured [hint: SSLSessionCache]");
- mc->nSessionCacheMode = SSL_SCMODE_NONE;
- }
-
- /*
- * initialize the mutex handling and session caching
- */
- ssl_mutex_init(s, p);
- ssl_scache_init(s, p);
-
- /*
- * Seed the Pseudo Random Number Generator (PRNG)
- */
- ssl_rand_seed(s, p, SSL_RSCTX_STARTUP, "Init: ");
-
- /*
- * allocate the temporary RSA keys and DH params
- */
- ssl_init_TmpKeysHandle(SSL_TKP_ALLOC, s, p);
-
- /*
- * initialize servers
- */
- ssl_log(s, SSL_LOG_INFO, "Init: Initializing (virtual) servers for SSL");
- for (s2 = s; s2 != NULL; s2 = s2->next) {
- sc = mySrvConfig(s2);
- /*
- * Either now skip this server when SSL is disabled for
- * it or give out some information about what we're
- * configuring.
- */
- if (!sc->bEnabled)
- continue;
- ssl_log(s2, SSL_LOG_INFO,
- "Init: Configuring server %s for SSL protocol",
- ssl_util_vhostid(p, s2));
-
- /*
- * Read the server certificate and key
- */
- ssl_init_ConfigureServer(s2, p, sc);
- }
-
- /*
- * Configuration consistency checks
- */
- ssl_init_CheckServers(s, p);
-
- /*
- * Announce mod_ssl and SSL library in HTTP Server field
- * as ``mod_ssl/X.X.X OpenSSL/X.X.X''
- */
- if ((cp = ssl_var_lookup(p, NULL, NULL, NULL, "SSL_VERSION_PRODUCT")) != NULL && cp[0] != NUL)
- ap_add_version_component(cp);
- ap_add_version_component(ssl_var_lookup(p, NULL, NULL, NULL, "SSL_VERSION_INTERFACE"));
- ap_add_version_component(ssl_var_lookup(p, NULL, NULL, NULL, "SSL_VERSION_LIBRARY"));
-
- return;
-}
-
-/*
- * Initialize SSL library (also already needed for the pass phrase dialog)
- */
-void ssl_init_SSLLibrary(void)
-{
-#ifdef WIN32
- CRYPTO_malloc_init();
-#endif
- SSL_load_error_strings();
- SSL_library_init();
- ssl_util_thread_setup();
- X509V3_add_standard_extensions();
- return;
-}
-
-/*
- * Support for external a Crypto Device ("engine"), usually
- * a hardware accellerator card for crypto operations.
- */
-#ifdef SSL_EXPERIMENTAL_ENGINE
-void ssl_init_Engine(server_rec *s, pool *p)
-{
- SSLModConfigRec *mc = myModConfig();
- ENGINE *e;
-
- if (mc->szCryptoDevice != NULL) {
- if ((e = ENGINE_by_id(mc->szCryptoDevice)) == NULL) {
- ssl_log(s, SSL_LOG_ERROR, "Init: Failed to load Crypto Device API `%s'",
- mc->szCryptoDevice);
- ssl_die();
- }
- if (strEQ(mc->szCryptoDevice, "chil"))
- ENGINE_ctrl(e, ENGINE_CTRL_CHIL_SET_FORKCHECK, 1, 0, 0);
- if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
- ssl_log(s, SSL_LOG_ERROR, "Init: Failed to enable Crypto Device API `%s'",
- mc->szCryptoDevice);
- ssl_die();
- }
- ENGINE_free(e);
- }
- return;
-}
-#endif
-
-/*
- * Handle the Temporary RSA Keys and DH Params
- */
-void ssl_init_TmpKeysHandle(int action, server_rec *s, pool *p)
-{
- SSLModConfigRec *mc = myModConfig();
- ssl_asn1_t *asn1;
- unsigned char *ucp;
- RSA *rsa;
- DH *dh;
-
- /* Generate Keys and Params */
- if (action == SSL_TKP_GEN) {
-
- /* seed PRNG */
- ssl_rand_seed(s, p, SSL_RSCTX_STARTUP, "Init: ");
-
- /* generate 512 bit RSA key */
- ssl_log(s, SSL_LOG_INFO, "Init: Generating temporary RSA private keys (512/1024 bits)");
- if ((rsa = RSA_generate_key(512, RSA_F4, NULL, NULL)) == NULL) {
- ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR,
- "Init: Failed to generate temporary 512 bit RSA private key");
- ssl_die();
- }
- asn1 = (ssl_asn1_t *)ssl_ds_table_push(mc->tTmpKeys, "RSA:512");
- asn1->nData = i2d_RSAPrivateKey(rsa, NULL);
- asn1->cpData = ap_palloc(mc->pPool, asn1->nData);
- ucp = asn1->cpData; i2d_RSAPrivateKey(rsa, &ucp); /* 2nd arg increments */
- RSA_free(rsa);
-
- /* generate 1024 bit RSA key */
- if ((rsa = RSA_generate_key(1024, RSA_F4, NULL, NULL)) == NULL) {
- ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR,
- "Init: Failed to generate temporary 1024 bit RSA private key");
- ssl_die();
- }
- asn1 = (ssl_asn1_t *)ssl_ds_table_push(mc->tTmpKeys, "RSA:1024");
- asn1->nData = i2d_RSAPrivateKey(rsa, NULL);
- asn1->cpData = ap_palloc(mc->pPool, asn1->nData);
- ucp = asn1->cpData; i2d_RSAPrivateKey(rsa, &ucp); /* 2nd arg increments */
- RSA_free(rsa);
-
- ssl_log(s, SSL_LOG_INFO, "Init: Configuring temporary DH parameters (512/1024 bits)");
-
- /* import 512 bit DH param */
- if ((dh = ssl_dh_GetTmpParam(512)) == NULL) {
- ssl_log(s, SSL_LOG_ERROR, "Init: Failed to import temporary 512 bit DH parameters");
- ssl_die();
- }
- asn1 = (ssl_asn1_t *)ssl_ds_table_push(mc->tTmpKeys, "DH:512");
- asn1->nData = i2d_DHparams(dh, NULL);
- asn1->cpData = ap_palloc(mc->pPool, asn1->nData);
- ucp = asn1->cpData; i2d_DHparams(dh, &ucp); /* 2nd arg increments */
- /* no need to free dh, it's static */
-
- /* import 1024 bit DH param */
- if ((dh = ssl_dh_GetTmpParam(1024)) == NULL) {
- ssl_log(s, SSL_LOG_ERROR, "Init: Failed to import temporary 1024 bit DH parameters");
- ssl_die();
- }
- asn1 = (ssl_asn1_t *)ssl_ds_table_push(mc->tTmpKeys, "DH:1024");
- asn1->nData = i2d_DHparams(dh, NULL);
- asn1->cpData = ap_palloc(mc->pPool, asn1->nData);
- ucp = asn1->cpData; i2d_DHparams(dh, &ucp); /* 2nd arg increments */
- /* no need to free dh, it's static */
- }
-
- /* Allocate Keys and Params */
- else if (action == SSL_TKP_ALLOC) {
-
- ssl_log(s, SSL_LOG_INFO, "Init: Configuring temporary RSA private keys (512/1024 bits)");
-
- /* allocate 512 bit RSA key */
- if ((asn1 = (ssl_asn1_t *)ssl_ds_table_get(mc->tTmpKeys, "RSA:512")) != NULL) {
- ucp = asn1->cpData;
- if ((mc->pTmpKeys[SSL_TKPIDX_RSA512] =
-#if SSL_LIBRARY_VERSION >= 0x00907000
- (void *)d2i_RSAPrivateKey(NULL, (const unsigned char **)&ucp, asn1->nData)) == NULL) {
-#else
- (void *)d2i_RSAPrivateKey(NULL, &ucp, asn1->nData)) == NULL) {
-#endif
- ssl_log(s, SSL_LOG_ERROR, "Init: Failed to load temporary 512 bit RSA private key");
- ssl_die();
- }
- }
-
- /* allocate 1024 bit RSA key */
- if ((asn1 = (ssl_asn1_t *)ssl_ds_table_get(mc->tTmpKeys, "RSA:1024")) != NULL) {
- ucp = asn1->cpData;
- if ((mc->pTmpKeys[SSL_TKPIDX_RSA1024] =
-#if SSL_LIBRARY_VERSION >= 0x00907000
- (void *)d2i_RSAPrivateKey(NULL, (const unsigned char **)&ucp, asn1->nData)) == NULL) {
-#else
- (void *)d2i_RSAPrivateKey(NULL, &ucp, asn1->nData)) == NULL) {
-#endif
- ssl_log(s, SSL_LOG_ERROR, "Init: Failed to load temporary 1024 bit RSA private key");
- ssl_die();
- }
- }
-
- ssl_log(s, SSL_LOG_INFO, "Init: Configuring temporary DH parameters (512/1024 bits)");
-
- /* allocate 512 bit DH param */
- if ((asn1 = (ssl_asn1_t *)ssl_ds_table_get(mc->tTmpKeys, "DH:512")) != NULL) {
- ucp = asn1->cpData;
- if ((mc->pTmpKeys[SSL_TKPIDX_DH512] =
-#if SSL_LIBRARY_VERSION >= 0x00907000
- (void *)d2i_DHparams(NULL, (const unsigned char **)&ucp, asn1->nData)) == NULL) {
-#else
- (void *)d2i_DHparams(NULL, &ucp, asn1->nData)) == NULL) {
-#endif
- ssl_log(s, SSL_LOG_ERROR, "Init: Failed to load temporary 512 bit DH parameters");
- ssl_die();
- }
- }
-
- /* allocate 1024 bit DH param */
- if ((asn1 = (ssl_asn1_t *)ssl_ds_table_get(mc->tTmpKeys, "DH:1024")) != NULL) {
- ucp = asn1->cpData;
- if ((mc->pTmpKeys[SSL_TKPIDX_DH1024] =
-#if SSL_LIBRARY_VERSION >= 0x00907000
- (void *)d2i_DHparams(NULL, (const unsigned char **)&ucp, asn1->nData)) == NULL) {
-#else
- (void *)d2i_DHparams(NULL, &ucp, asn1->nData)) == NULL) {
-#endif
- ssl_log(s, SSL_LOG_ERROR, "Init: Failed to load temporary 1024 bit DH parameters");
- ssl_die();
- }
- }
- }
-
- /* Free Keys and Params */
- else if (action == SSL_TKP_FREE) {
- if (mc->pTmpKeys[SSL_TKPIDX_RSA512] != NULL) {
- RSA_free((RSA *)mc->pTmpKeys[SSL_TKPIDX_RSA512]);
- mc->pTmpKeys[SSL_TKPIDX_RSA512] = NULL;
- }
- if (mc->pTmpKeys[SSL_TKPIDX_RSA1024] != NULL) {
- RSA_free((RSA *)mc->pTmpKeys[SSL_TKPIDX_RSA1024]);
- mc->pTmpKeys[SSL_TKPIDX_RSA1024] = NULL;
- }
- if (mc->pTmpKeys[SSL_TKPIDX_DH512] != NULL) {
- DH_free((DH *)mc->pTmpKeys[SSL_TKPIDX_DH512]);
- mc->pTmpKeys[SSL_TKPIDX_DH512] = NULL;
- }
- if (mc->pTmpKeys[SSL_TKPIDX_DH1024] != NULL) {
- DH_free((DH *)mc->pTmpKeys[SSL_TKPIDX_DH1024]);
- mc->pTmpKeys[SSL_TKPIDX_DH1024] = NULL;
- }
- }
- return;
-}
-
-/*
- * Configure a particular server
- */
-void ssl_init_ConfigureServer(server_rec *s, pool *p, SSLSrvConfigRec *sc)
-{
- SSLModConfigRec *mc = myModConfig();
- int nVerify;
- char *cpVHostID;
- EVP_PKEY *pKey;
- SSL_CTX *ctx;
- STACK_OF(X509_NAME) *skCAList;
- ssl_asn1_t *asn1;
- unsigned char *ucp;
- char *cp;
- BOOL ok;
- BOOL bSkipFirst;
- int isca, pathlen;
- int i, n;
-
- /*
- * Create the server host:port string because we need it a lot
- */
- cpVHostID = ssl_util_vhostid(p, s);
-
- /*
- * Now check for important parameters and the
- * possibility that the user forgot to set them.
- */
- if (sc->szPublicCertFile[0] == NULL) {
- ssl_log(s, SSL_LOG_ERROR,
- "Init: (%s) No SSL Certificate set [hint: SSLCertificateFile]",
- cpVHostID);
- ssl_die();
- }
-
- /*
- * Check for problematic re-initializations
- */
- if (sc->pPublicCert[SSL_AIDX_RSA] != NULL ||
- sc->pPublicCert[SSL_AIDX_DSA] != NULL ) {
- ssl_log(s, SSL_LOG_ERROR,
- "Init: (%s) Illegal attempt to re-initialise SSL for server "
- "(theoretically shouldn't happen!)", cpVHostID);
- ssl_die();
- }
-
- /*
- * Create the new per-server SSL context
- */
- if (sc->nProtocol == SSL_PROTOCOL_NONE) {
- ssl_log(s, SSL_LOG_ERROR,
- "Init: (%s) No SSL protocols available [hint: SSLProtocol]",
- cpVHostID);
- ssl_die();
- }
- cp = ap_pstrcat(p, (sc->nProtocol & SSL_PROTOCOL_SSLV2 ? "SSLv2, " : ""),
- (sc->nProtocol & SSL_PROTOCOL_SSLV3 ? "SSLv3, " : ""),
- (sc->nProtocol & SSL_PROTOCOL_TLSV1 ? "TLSv1, " : ""), NULL);
- cp[strlen(cp)-2] = NUL;
- ssl_log(s, SSL_LOG_TRACE,
- "Init: (%s) Creating new SSL context (protocols: %s)", cpVHostID, cp);
- if (sc->nProtocol == SSL_PROTOCOL_SSLV2)
- ctx = SSL_CTX_new(SSLv2_server_method()); /* only SSLv2 is left */
- else
- ctx = SSL_CTX_new(SSLv23_server_method()); /* be more flexible */
- SSL_CTX_set_options(ctx, SSL_OP_ALL);
- if (!(sc->nProtocol & SSL_PROTOCOL_SSLV2))
- SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
- if (!(sc->nProtocol & SSL_PROTOCOL_SSLV3))
- SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3);
- if (!(sc->nProtocol & SSL_PROTOCOL_TLSV1))
- SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1);
- SSL_CTX_set_app_data(ctx, s);
- sc->pSSLCtx = ctx;
-
- /*
- * Configure additional context ingredients
- */
- SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE);
- if (mc->nSessionCacheMode == SSL_SCMODE_NONE)
- SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
- else
- SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_SERVER);
-
- /*
- * Configure callbacks for SSL context
- */
- nVerify = SSL_VERIFY_NONE;
- if (sc->nVerifyClient == SSL_CVERIFY_REQUIRE)
- nVerify |= SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT;
- if ( (sc->nVerifyClient == SSL_CVERIFY_OPTIONAL)
- || (sc->nVerifyClient == SSL_CVERIFY_OPTIONAL_NO_CA) )
- nVerify |= SSL_VERIFY_PEER;
- SSL_CTX_set_verify(ctx, nVerify, ssl_callback_SSLVerify);
- 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);
- SSL_CTX_set_tmp_rsa_callback(ctx, ssl_callback_TmpRSA);
- SSL_CTX_set_tmp_dh_callback(ctx, ssl_callback_TmpDH);
- SSL_CTX_set_info_callback(ctx, ssl_callback_LogTracingState);
-
- /*
- * Configure SSL Cipher Suite
- */
- if (sc->szCipherSuite != NULL) {
- ssl_log(s, SSL_LOG_TRACE,
- "Init: (%s) Configuring permitted SSL ciphers [%s]",
- cpVHostID, sc->szCipherSuite);
- if (!SSL_CTX_set_cipher_list(ctx, sc->szCipherSuite)) {
- ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR,
- "Init: (%s) Unable to configure permitted SSL ciphers",
- cpVHostID);
- ssl_die();
- }
- }
-
- /*
- * Configure Client Authentication details
- */
- if (sc->szCACertificateFile != NULL || sc->szCACertificatePath != NULL) {
- ssl_log(s, SSL_LOG_TRACE,
- "Init: (%s) Configuring client authentication", cpVHostID);
- if (!SSL_CTX_load_verify_locations(ctx,
- sc->szCACertificateFile,
- sc->szCACertificatePath)) {
- ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR,
- "Init: (%s) Unable to configure verify locations "
- "for client authentication", cpVHostID);
- ssl_die();
- }
- if ((skCAList = ssl_init_FindCAList(s, p, sc->szCACertificateFile,
- sc->szCACertificatePath)) == NULL) {
- ssl_log(s, SSL_LOG_ERROR,
- "Init: (%s) Unable to determine list of available "
- "CA certificates for client authentication", cpVHostID);
- ssl_die();
- }
- SSL_CTX_set_client_CA_list(sc->pSSLCtx, skCAList);
- }
-
- /*
- * Configure Certificate Revocation List (CRL) Details
- */
- if (sc->szCARevocationFile != NULL || sc->szCARevocationPath != NULL) {
- ssl_log(s, SSL_LOG_TRACE,
- "Init: (%s) Configuring certificate revocation facility", cpVHostID);
- if ((sc->pRevocationStore =
- SSL_X509_STORE_create(sc->szCARevocationFile,
- sc->szCARevocationPath)) == NULL) {
- ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR,
- "Init: (%s) Unable to configure X.509 CRL storage "
- "for certificate revocation", cpVHostID);
- ssl_die();
- }
- }
-
- /*
- * Give a warning when no CAs were configured but client authentication
- * should take place. This cannot work.
- */
- if (sc->nVerifyClient == SSL_CVERIFY_REQUIRE) {
- skCAList = SSL_CTX_get_client_CA_list(ctx);
- if (sk_X509_NAME_num(skCAList) == 0)
- ssl_log(s, SSL_LOG_WARN,
- "Init: Ops, you want to request client authentication, "
- "but no CAs are known for verification!? "
- "[Hint: SSLCACertificate*]");
- }
-
- /*
- * Configure server certificate(s)
- */
- ok = FALSE;
- cp = ap_psprintf(p, "%s:RSA", cpVHostID);
- if ((asn1 = (ssl_asn1_t *)ssl_ds_table_get(mc->tPublicCert, cp)) != NULL) {
- ssl_log(s, SSL_LOG_TRACE,
- "Init: (%s) Configuring RSA server certificate", cpVHostID);
- ucp = asn1->cpData;
- if ((sc->pPublicCert[SSL_AIDX_RSA] = d2i_X509(NULL, &ucp, asn1->nData)) == NULL) {
- ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR,
- "Init: (%s) Unable to import RSA server certificate",
- cpVHostID);
- ssl_die();
- }
- if (SSL_CTX_use_certificate(ctx, sc->pPublicCert[SSL_AIDX_RSA]) <= 0) {
- ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR,
- "Init: (%s) Unable to configure RSA server certificate",
- cpVHostID);
- ssl_die();
- }
- ok = TRUE;
- }
- cp = ap_psprintf(p, "%s:DSA", cpVHostID);
- if ((asn1 = (ssl_asn1_t *)ssl_ds_table_get(mc->tPublicCert, cp)) != NULL) {
- ssl_log(s, SSL_LOG_TRACE,
- "Init: (%s) Configuring DSA server certificate", cpVHostID);
- ucp = asn1->cpData;
- if ((sc->pPublicCert[SSL_AIDX_DSA] = d2i_X509(NULL, &ucp, asn1->nData)) == NULL) {
- ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR,
- "Init: (%s) Unable to import DSA server certificate",
- cpVHostID);
- ssl_die();
- }
- if (SSL_CTX_use_certificate(ctx, sc->pPublicCert[SSL_AIDX_DSA]) <= 0) {
- ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR,
- "Init: (%s) Unable to configure DSA server certificate",
- cpVHostID);
- ssl_die();
- }
- ok = TRUE;
- }
- if (!ok) {
- ssl_log(s, SSL_LOG_ERROR,
- "Init: (%s) Ops, no RSA or DSA server certificate found?!", cpVHostID);
- ssl_log(s, SSL_LOG_ERROR,
- "Init: (%s) You have to perform a *full* server restart when you added or removed a certificate and/or key file", cpVHostID);
- ssl_die();
- }
-
- /*
- * Some information about the certificate(s)
- */
- for (i = 0; i < SSL_AIDX_MAX; i++) {
- if (sc->pPublicCert[i] != NULL) {
- if (SSL_X509_isSGC(sc->pPublicCert[i])) {
- ssl_log(s, SSL_LOG_INFO,
- "Init: (%s) %s server certificate enables "
- "Server Gated Cryptography (SGC)",
- cpVHostID, (i == SSL_AIDX_RSA ? "RSA" : "DSA"));
- }
- if (SSL_X509_getBC(sc->pPublicCert[i], &isca, &pathlen)) {
- if (isca)
- ssl_log(s, SSL_LOG_WARN,
- "Init: (%s) %s server certificate is a CA certificate "
- "(BasicConstraints: CA == TRUE !?)",
- cpVHostID, (i == SSL_AIDX_RSA ? "RSA" : "DSA"));
- if (pathlen > 0)
- ssl_log(s, SSL_LOG_WARN,
- "Init: (%s) %s server certificate is not a leaf certificate "
- "(BasicConstraints: pathlen == %d > 0 !?)",
- cpVHostID, (i == SSL_AIDX_RSA ? "RSA" : "DSA"), pathlen);
- }
- if (SSL_X509_getCN(p, sc->pPublicCert[i], &cp)) {
- if (ap_is_fnmatch(cp) &&
- !ap_fnmatch(cp, s->server_hostname, FNM_PERIOD|FNM_CASE_BLIND)) {
- ssl_log(s, SSL_LOG_WARN,
- "Init: (%s) %s server certificate wildcard CommonName (CN) `%s' "
- "does NOT match server name!?", cpVHostID,
- (i == SSL_AIDX_RSA ? "RSA" : "DSA"), cp);
- }
- else if (strNE(s->server_hostname, cp)) {
- ssl_log(s, SSL_LOG_WARN,
- "Init: (%s) %s server certificate CommonName (CN) `%s' "
- "does NOT match server name!?", cpVHostID,
- (i == SSL_AIDX_RSA ? "RSA" : "DSA"), cp);
- }
- }
- }
- }
-
- /*
- * Configure server private key(s)
- */
- ok = FALSE;
- cp = ap_psprintf(p, "%s:RSA", cpVHostID);
- if ((asn1 = (ssl_asn1_t *)ssl_ds_table_get(mc->tPrivateKey, cp)) != NULL) {
- ssl_log(s, SSL_LOG_TRACE,
- "Init: (%s) Configuring RSA server private key", cpVHostID);
- ucp = asn1->cpData;
- if ((sc->pPrivateKey[SSL_AIDX_RSA] =
- d2i_PrivateKey(EVP_PKEY_RSA, NULL, &ucp, asn1->nData)) == NULL) {
- ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR,
- "Init: (%s) Unable to import RSA server private key",
- cpVHostID);
- ssl_die();
- }
- if (SSL_CTX_use_PrivateKey(ctx, sc->pPrivateKey[SSL_AIDX_RSA]) <= 0) {
- ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR,
- "Init: (%s) Unable to configure RSA server private key",
- cpVHostID);
- ssl_die();
- }
- ok = TRUE;
- }
- cp = ap_psprintf(p, "%s:DSA", cpVHostID);
- if ((asn1 = (ssl_asn1_t *)ssl_ds_table_get(mc->tPrivateKey, cp)) != NULL) {
- ssl_log(s, SSL_LOG_TRACE,
- "Init: (%s) Configuring DSA server private key", cpVHostID);
- ucp = asn1->cpData;
- if ((sc->pPrivateKey[SSL_AIDX_DSA] =
- d2i_PrivateKey(EVP_PKEY_DSA, NULL, &ucp, asn1->nData)) == NULL) {
- ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR,
- "Init: (%s) Unable to import DSA server private key",
- cpVHostID);
- ssl_die();
- }
- if (SSL_CTX_use_PrivateKey(ctx, sc->pPrivateKey[SSL_AIDX_DSA]) <= 0) {
- ssl_log(s, SSL_LOG_ERROR|SSL_ADD_SSLERR,
- "Init: (%s) Unable to configure DSA server private key",
- cpVHostID);
- ssl_die();
- }
- ok = TRUE;
- }
- if (!ok) {
- ssl_log(s, SSL_LOG_ERROR,
- "Init: (%s) Ops, no RSA or DSA server private key found?!", cpVHostID);
- ssl_die();
- }
-
- /*
- * Optionally copy DSA parameters for certificate from private key
- * (see http://www.psy.uq.edu.au/~ftp/Crypto/ssleay/TODO.html)
- */
- if ( sc->pPublicCert[SSL_AIDX_DSA] != NULL
- && sc->pPrivateKey[SSL_AIDX_DSA] != NULL) {
- pKey = X509_get_pubkey(sc->pPublicCert[SSL_AIDX_DSA]);
- if ( pKey != NULL
- && EVP_PKEY_type(pKey->type) == EVP_PKEY_DSA
- && EVP_PKEY_missing_parameters(pKey))
- EVP_PKEY_copy_parameters(pKey, sc->pPrivateKey[SSL_AIDX_DSA]);
- }
-
- /*
- * Optionally configure extra server certificate chain certificates.
- * This is usually done by OpenSSL automatically when one of the
- * server cert issuers are found under SSLCACertificatePath or in
- * SSLCACertificateFile. But because these are intended for client
- * authentication it can conflict. For instance when you use a
- * Global ID server certificate you've to send out the intermediate
- * CA certificate, too. When you would just configure this with
- * SSLCACertificateFile and also use client authentication mod_ssl
- * would accept all clients also issued by this CA. Obviously this
- * isn't what we want in this situation. So this feature here exists
- * to allow one to explicity configure CA certificates which are
- * used only for the server certificate chain.
- */
- if (sc->szCertificateChain != NULL) {
- bSkipFirst = FALSE;
- for (i = 0; i < SSL_AIDX_MAX && sc->szPublicCertFile[i] != NULL; i++) {
- if (strEQ(sc->szPublicCertFile[i], sc->szCertificateChain)) {
- bSkipFirst = TRUE;
- break;
- }
- }
- if ((n = SSL_CTX_use_certificate_chain(ctx, sc->szCertificateChain,
- bSkipFirst, NULL)) < 0) {
- ssl_log(s, SSL_LOG_ERROR,
- "Init: (%s) Failed to configure CA certificate chain!", cpVHostID);
- ssl_die();
- }
- ssl_log(s, SSL_LOG_TRACE, "Init: (%s) Configuring "
- "server certificate chain (%d CA certificate%s)", cpVHostID,
- n, n == 1 ? "" : "s");
- }
-
-#ifdef SSL_VENDOR
- ap_hook_use("ap::mod_ssl::vendor::configure_server",
- AP_HOOK_SIG4(void,ptr,ptr,ptr), AP_HOOK_ALL,
- s, p, sc);
-#endif
-
- return;
-}
-
-void ssl_init_CheckServers(server_rec *sm, pool *p)
-{
- server_rec *s;
- server_rec **ps;
- SSLSrvConfigRec *sc;
- ssl_ds_table *t;
- pool *sp;
- char *key;
- BOOL bConflict;
-
- /*
- * Give out warnings when a server has HTTPS configured
- * for the HTTP port or vice versa
- */
- for (s = sm; s != NULL; s = s->next) {
- sc = mySrvConfig(s);
- if (sc->bEnabled && s->port == DEFAULT_HTTP_PORT)
- ssl_log(sm, SSL_LOG_WARN,
- "Init: (%s) You configured HTTPS(%d) on the standard HTTP(%d) port!",
- ssl_util_vhostid(p, s), DEFAULT_HTTPS_PORT, DEFAULT_HTTP_PORT);
- if (!sc->bEnabled && s->port == DEFAULT_HTTPS_PORT)
- ssl_log(sm, SSL_LOG_WARN,
- "Init: (%s) You configured HTTP(%d) on the standard HTTPS(%d) port!",
- ssl_util_vhostid(p, s), DEFAULT_HTTP_PORT, DEFAULT_HTTPS_PORT);
- }
-
- /*
- * Give out warnings when more than one SSL-aware virtual server uses the
- * same IP:port. This doesn't work because mod_ssl then will always use
- * just the certificate/keys of one virtual host (which one cannot be said
- * easily - but that doesn't matter here).
- */
- sp = ap_make_sub_pool(p);
- t = ssl_ds_table_make(sp, sizeof(server_rec *));
- bConflict = FALSE;
- for (s = sm; s != NULL; s = s->next) {
- sc = mySrvConfig(s);
- if (!sc->bEnabled)
- continue;
- key = ap_psprintf(sp, "%pA:%u", &s->addrs->host_addr, s->addrs->host_port);
- ps = ssl_ds_table_get(t, key);
- if (ps != NULL) {
- ssl_log(sm, SSL_LOG_WARN,
- "Init: SSL server IP/port conflict: %s (%s:%d) vs. %s (%s:%d)",
- ssl_util_vhostid(p, s),
- (s->defn_name != NULL ? s->defn_name : "unknown"),
- s->defn_line_number,
- ssl_util_vhostid(p, *ps),
- ((*ps)->defn_name != NULL ? (*ps)->defn_name : "unknown"),
- (*ps)->defn_line_number);
- bConflict = TRUE;
- continue;
- }
- ps = ssl_ds_table_push(t, key);
- *ps = s;
- }
- ssl_ds_table_kill(t);
- ap_destroy_pool(sp);
- if (bConflict)
- ssl_log(sm, SSL_LOG_WARN,
- "Init: You should not use name-based virtual hosts in conjunction with SSL!!");
-
- return;
-}
-
-static int ssl_init_FindCAList_X509NameCmp(X509_NAME **a, X509_NAME **b)
-{
- return(X509_NAME_cmp(*a, *b));
-}
-
-STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s, pool *pp, char *cpCAfile, char *cpCApath)
-{
- STACK_OF(X509_NAME) *skCAList;
- STACK_OF(X509_NAME) *sk;
- DIR *dir;
- struct DIR_TYPE *direntry;
- char *cp;
- pool *p;
- int n;
-
- /*
- * Use a subpool so we don't bloat up the server pool which
- * is remains in memory for the complete operation time of
- * the server.
- */
- p = ap_make_sub_pool(pp);
-
- /*
- * Start with a empty stack/list where new
- * entries get added in sorted order.
- */
- skCAList = sk_X509_NAME_new(ssl_init_FindCAList_X509NameCmp);
-
- /*
- * Process CA certificate bundle file
- */
- if (cpCAfile != NULL) {
- sk = SSL_load_client_CA_file(cpCAfile);
- for(n = 0; sk != NULL && n < sk_X509_NAME_num(sk); n++) {
- ssl_log(s, SSL_LOG_TRACE,
- "CA certificate: %s",
- X509_NAME_oneline(sk_X509_NAME_value(sk, n), NULL, 0));
- if (sk_X509_NAME_find(skCAList, sk_X509_NAME_value(sk, n)) < 0)
- sk_X509_NAME_push(skCAList, sk_X509_NAME_value(sk, n));
- }
- }
-
- /*
- * Process CA certificate path files
- */
- if (cpCApath != NULL) {
- dir = ap_popendir(p, cpCApath);
- while ((direntry = readdir(dir)) != NULL) {
- cp = ap_pstrcat(p, cpCApath, "/", direntry->d_name, NULL);
- sk = SSL_load_client_CA_file(cp);
- for(n = 0; sk != NULL && n < sk_X509_NAME_num(sk); n++) {
- ssl_log(s, SSL_LOG_TRACE,
- "CA certificate: %s",
- X509_NAME_oneline(sk_X509_NAME_value(sk, n), NULL, 0));
- if (sk_X509_NAME_find(skCAList, sk_X509_NAME_value(sk, n)) < 0)
- sk_X509_NAME_push(skCAList, sk_X509_NAME_value(sk, n));
- }
- }
- ap_pclosedir(p, dir);
- }
-
- /*
- * Cleanup
- */
- sk_X509_NAME_set_cmp_func(skCAList, NULL);
- ap_destroy_pool(p);
-
- return skCAList;
-}
-
-void ssl_init_Child(server_rec *s, pool *p)
-{
- /* open the mutex lockfile */
- ssl_mutex_reinit(s, p);
- return;
-}
-
-void ssl_init_ChildKill(void *data)
-{
- /* currently nothing to do */
- return;
-}
-
-void ssl_init_ModuleKill(void *data)
-{
- SSLSrvConfigRec *sc;
- server_rec *s = (server_rec *)data;
-
- /*
- * Drop the session cache and mutex
- */
- ssl_scache_kill(s);
- ssl_mutex_kill(s);
-
- /*
- * Destroy the temporary keys and params
- */
- ssl_init_TmpKeysHandle(SSL_TKP_FREE, s, NULL);
-
- /*
- * Free the non-pool allocated structures
- * in the per-server configurations
- */
- for (; s != NULL; s = s->next) {
- sc = mySrvConfig(s);
- if (sc->pPublicCert[SSL_AIDX_RSA] != NULL) {
- X509_free(sc->pPublicCert[SSL_AIDX_RSA]);
- sc->pPublicCert[SSL_AIDX_RSA] = NULL;
- }
- if (sc->pPublicCert[SSL_AIDX_DSA] != NULL) {
- X509_free(sc->pPublicCert[SSL_AIDX_DSA]);
- sc->pPublicCert[SSL_AIDX_DSA] = NULL;
- }
- if (sc->pPrivateKey[SSL_AIDX_RSA] != NULL) {
- EVP_PKEY_free(sc->pPrivateKey[SSL_AIDX_RSA]);
- sc->pPrivateKey[SSL_AIDX_RSA] = NULL;
- }
- if (sc->pPrivateKey[SSL_AIDX_DSA] != NULL) {
- EVP_PKEY_free(sc->pPrivateKey[SSL_AIDX_DSA]);
- sc->pPrivateKey[SSL_AIDX_DSA] = NULL;
- }
- if (sc->pSSLCtx != NULL) {
- SSL_CTX_free(sc->pSSLCtx);
- sc->pSSLCtx = NULL;
- }
- }
-
- /*
- * Try to kill the internals of the SSL library.
- */
-#ifdef SHARED_MODULE
- ERR_free_strings();
- ERR_remove_state(0);
- EVP_cleanup();
-#endif
-
- return;
-}
-