📄 ssl_engine_init.c
字号:
/* Copyright 2001-2005 The Apache Software Foundation or its licensors, as * applicable. * * Licensed 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_engine_init.c * Initialization of Servers */ /* ``Recursive, adj.; see Recursive.'' -- Unknown */#include "ssl_private.h"/* _________________________________________________________________**** Module Initialization** _________________________________________________________________*/static char *ssl_add_version_component(apr_pool_t *p, server_rec *s, char *name){ char *val = ssl_var_lookup(p, s, NULL, NULL, name); if (val && *val) { ap_add_version_component(p, val); } return val;}static char *version_components[] = { "SSL_VERSION_PRODUCT", "SSL_VERSION_INTERFACE", "SSL_VERSION_LIBRARY", NULL};static void ssl_add_version_components(apr_pool_t *p, server_rec *s){ char *vals[sizeof(version_components)/sizeof(char *)]; int i; for (i=0; version_components[i]; i++) { vals[i] = ssl_add_version_component(p, s, version_components[i]); } ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, "Server: %s, Interface: %s, Library: %s", AP_SERVER_BASEVERSION, vals[1], /* SSL_VERSION_INTERFACE */ vals[2]); /* SSL_VERSION_LIBRARY */}/* * Handle the Temporary RSA Keys and DH Params */#define MODSSL_TMP_KEY_FREE(mc, type, idx) \ if (mc->pTmpKeys[idx]) { \ type##_free((type *)mc->pTmpKeys[idx]); \ mc->pTmpKeys[idx] = NULL; \ }#define MODSSL_TMP_KEYS_FREE(mc, type) \ MODSSL_TMP_KEY_FREE(mc, type, SSL_TMP_KEY_##type##_512); \ MODSSL_TMP_KEY_FREE(mc, type, SSL_TMP_KEY_##type##_1024)static void ssl_tmp_keys_free(server_rec *s){ SSLModConfigRec *mc = myModConfig(s); MODSSL_TMP_KEYS_FREE(mc, RSA); MODSSL_TMP_KEYS_FREE(mc, DH);}static int ssl_tmp_key_init_rsa(server_rec *s, int bits, int idx){ SSLModConfigRec *mc = myModConfig(s); if (!(mc->pTmpKeys[idx] = RSA_generate_key(bits, RSA_F4, NULL, NULL))) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "Init: Failed to generate temporary " "%d bit RSA private key", bits); return !OK; } return OK;}static int ssl_tmp_key_init_dh(server_rec *s, int bits, int idx){ SSLModConfigRec *mc = myModConfig(s); if (!(mc->pTmpKeys[idx] = ssl_dh_GetTmpParam(bits))) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "Init: Failed to generate temporary " "%d bit DH parameters", bits); return !OK; } return OK;}#define MODSSL_TMP_KEY_INIT_RSA(s, bits) \ ssl_tmp_key_init_rsa(s, bits, SSL_TMP_KEY_RSA_##bits)#define MODSSL_TMP_KEY_INIT_DH(s, bits) \ ssl_tmp_key_init_dh(s, bits, SSL_TMP_KEY_DH_##bits)static int ssl_tmp_keys_init(server_rec *s){ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, "Init: Generating temporary RSA private keys (512/1024 bits)"); if (MODSSL_TMP_KEY_INIT_RSA(s, 512) || MODSSL_TMP_KEY_INIT_RSA(s, 1024)) { return !OK; } ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, "Init: Generating temporary DH parameters (512/1024 bits)"); if (MODSSL_TMP_KEY_INIT_DH(s, 512) || MODSSL_TMP_KEY_INIT_DH(s, 1024)) { return !OK; } return OK;}/* * Per-module initialization */int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog, apr_pool_t *ptemp, server_rec *base_server){ SSLModConfigRec *mc = myModConfig(base_server); SSLSrvConfigRec *sc; server_rec *s; /* We initialize mc->pid per-process in the child init, * but it should be initialized for startup before we * call ssl_rand_seed() below. */ mc->pid = getpid(); /* * Let us cleanup on restarts and exists */ apr_pool_cleanup_register(p, base_server, ssl_init_ModuleKill, apr_pool_cleanup_null); /* * Any init round fixes the global config */ ssl_config_global_create(base_server); /* just to avoid problems */ ssl_config_global_fix(mc); /* * try to fix the configuration and open the dedicated SSL * logfile as early as possible */ for (s = base_server; s; s = s->next) { sc = mySrvConfig(s); if (sc->server) { sc->server->sc = sc; } if (sc->proxy) { sc->proxy->sc = sc; } /* * Create the server host:port string because we need it a lot */ sc->vhost_id = ssl_util_vhostid(p, s); sc->vhost_id_len = strlen(sc->vhost_id); if (ap_get_server_protocol(s) && strcmp("https", ap_get_server_protocol(s)) == 0) { sc->enabled = SSL_ENABLED_TRUE; } /* If sc->enabled is UNSET, then SSL is optional on this vhost */ /* Fix up stuff that may not have been set */ if (sc->enabled == SSL_ENABLED_UNSET) { sc->enabled = SSL_ENABLED_FALSE; } if (sc->proxy_enabled == UNSET) { sc->proxy_enabled = FALSE; } if (sc->session_cache_timeout == UNSET) { sc->session_cache_timeout = SSL_SESSION_CACHE_TIMEOUT; } if (sc->server->pphrase_dialog_type == SSL_PPTYPE_UNSET) { sc->server->pphrase_dialog_type = SSL_PPTYPE_BUILTIN; } } /* * SSL external crypto device ("engine") support */#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT) ssl_init_Engine(base_server, p);#endif#if APR_HAS_THREADS ssl_util_thread_setup(p);#endif ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, "Init: Initialized %s library", SSL_LIBRARY_NAME); /* * Seed the Pseudo Random Number Generator (PRNG) * only need ptemp here; nothing inside allocated from the pool * needs to live once we return from ssl_rand_seed(). */ ssl_rand_seed(base_server, ptemp, SSL_RSCTX_STARTUP, "Init: "); /* * read server private keys/public certs into memory. * decrypting any encrypted keys via configured SSLPassPhraseDialogs * anything that needs to live longer than ptemp needs to also survive * restarts, in which case they'll live inside s->process->pool. */ ssl_pphrase_Handle(base_server, ptemp); if (ssl_tmp_keys_init(base_server)) { return !OK; } /* * initialize the mutex handling */ if (!ssl_mutex_init(base_server, p)) { return HTTP_INTERNAL_SERVER_ERROR; } /* * initialize session caching */ ssl_scache_init(base_server, p); /* * initialize servers */ ap_log_error(APLOG_MARK, APLOG_INFO, 0, base_server, "Init: Initializing (virtual) servers for SSL"); for (s = base_server; s; s = s->next) { sc = mySrvConfig(s); /* * Either now skip this server when SSL is disabled for * it or give out some information about what we're * configuring. */ /* * Read the server certificate and key */ ssl_init_ConfigureServer(s, p, ptemp, sc); } /* * Configuration consistency checks */ ssl_init_CheckServers(base_server, ptemp); /* * Announce mod_ssl and SSL library in HTTP Server field * as ``mod_ssl/X.X.X OpenSSL/X.X.X'' */ ssl_add_version_components(p, base_server); SSL_init_app_data2_idx(); /* for SSL_get_app_data2() at request time */ return OK;}/* * Support for external a Crypto Device ("engine"), usually * a hardware accellerator card for crypto operations. */#if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)void ssl_init_Engine(server_rec *s, apr_pool_t *p){ SSLModConfigRec *mc = myModConfig(s); ENGINE *e; if (mc->szCryptoDevice) { if (!(e = ENGINE_by_id(mc->szCryptoDevice))) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "Init: Failed to load Crypto Device API `%s'", mc->szCryptoDevice); ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); 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)) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "Init: Failed to enable Crypto Device API `%s'", mc->szCryptoDevice); ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s); ssl_die(); } ENGINE_free(e); }}#endifstatic void ssl_init_server_check(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp, modssl_ctx_t *mctx){ /* * 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, "No SSL Certificate set [hint: SSLCertificateFile]"); ssl_die(); } /* * Check for problematic re-initializations */ if (mctx->pks->certs[SSL_AIDX_RSA] || mctx->pks->certs[SSL_AIDX_DSA]) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "Illegal attempt to re-initialise SSL for server " "(theoretically shouldn't happen!)"); ssl_die(); }}static void ssl_init_ctx_protocol(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp, modssl_ctx_t *mctx){ SSL_CTX *ctx = NULL; SSL_METHOD *method = NULL; char *cp; int protocol = mctx->protocol; /* * Create the new per-server SSL context */ if (protocol == SSL_PROTOCOL_NONE) { ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, "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, "Creating new SSL context (protocols: %s)", cp); if (protocol == SSL_PROTOCOL_SSLV2) { method = mctx->pkp ? SSLv2_client_method() : /* proxy */ SSLv2_server_method(); /* server */ ctx = SSL_CTX_new(method); /* only SSLv2 is left */ } else { method = mctx->pkp ? SSLv23_client_method() : /* proxy */ SSLv23_server_method(); /* server */ ctx = SSL_CTX_new(method); /* be more flexible */ } mctx->ssl_ctx = ctx; SSL_CTX_set_options(ctx, SSL_OP_ALL);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -