1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2 * contributor license agreements. See the NOTICE file distributed with
3 * this work for additional information regarding copyright ownership.
4 * The ASF licenses this file to You under the Apache License, Version 2.0
5 * (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * _ __ ___ ___ __| | ___ ___| | mod_ssl
19 * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL
20 * | | | | | | (_) | (_| | \__ \__ \ |
21 * |_| |_| |_|\___/ \__,_|___|___/___/_|
24 * Apache API interface structures
27 #include "ssl_private.h"
30 #include "util_mutex.h"
31 #include "ap_provider.h"
37 int ssl_running_on_valgrind = 0;
41 * the table of configuration directives we provide
44 #define SSL_CMD_ALL(name, args, desc) \
45 AP_INIT_##args("SSL"#name, ssl_cmd_SSL##name, \
46 NULL, RSRC_CONF|OR_AUTHCFG, desc),
48 #define SSL_CMD_SRV(name, args, desc) \
49 AP_INIT_##args("SSL"#name, ssl_cmd_SSL##name, \
50 NULL, RSRC_CONF, desc),
52 #define SSL_CMD_DIR(name, type, args, desc) \
53 AP_INIT_##args("SSL"#name, ssl_cmd_SSL##name, \
54 NULL, OR_##type, desc),
56 #define AP_END_CMD { NULL }
58 static const command_rec ssl_config_cmds[] = {
60 * Global (main-server) context configuration directives
62 SSL_CMD_SRV(PassPhraseDialog, TAKE1,
63 "SSL dialog mechanism for the pass phrase query "
64 "('builtin', '|/path/to/pipe_program', "
65 "or 'exec:/path/to/cgi_program')")
66 SSL_CMD_SRV(SessionCache, TAKE1,
67 "SSL Session Cache storage "
68 "('none', 'nonenotnull', 'dbm:/path/to/file')")
69 #if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
70 SSL_CMD_SRV(CryptoDevice, TAKE1,
71 "SSL external Crypto Device usage "
74 SSL_CMD_SRV(RandomSeed, TAKE23,
75 "SSL Pseudo Random Number Generator (PRNG) seeding source "
76 "('startup|connect builtin|file:/path|exec:/path [bytes]')")
79 * Per-server context configuration directives
81 SSL_CMD_SRV(Engine, TAKE1,
82 "SSL switch for the protocol engine "
84 SSL_CMD_SRV(FIPS, FLAG,
85 "Enable FIPS-140 mode "
87 SSL_CMD_ALL(CipherSuite, TAKE1,
88 "Colon-delimited list of permitted SSL Ciphers "
89 "('XXX:...:XXX' - see manual)")
90 SSL_CMD_SRV(CertificateFile, TAKE1,
91 "SSL Server Certificate file "
92 "('/path/to/file' - PEM or DER encoded)")
93 SSL_CMD_SRV(CertificateKeyFile, TAKE1,
94 "SSL Server Private Key file "
95 "('/path/to/file' - PEM or DER encoded)")
96 SSL_CMD_SRV(CertificateChainFile, TAKE1,
97 "SSL Server CA Certificate Chain file "
98 "('/path/to/file' - PEM encoded)")
99 SSL_CMD_SRV(PKCS7CertificateFile, TAKE1,
100 "PKCS#7 file containing server certificate and chain"
101 " certificates ('/path/to/file' - PEM encoded)")
102 #ifdef HAVE_TLS_SESSION_TICKETS
103 SSL_CMD_SRV(SessionTicketKeyFile, TAKE1,
104 "TLS session ticket encryption/decryption key file (RFC 5077) "
105 "('/path/to/file' - file with 48 bytes of random data)")
107 SSL_CMD_ALL(CACertificatePath, TAKE1,
108 "SSL CA Certificate path "
109 "('/path/to/dir' - contains PEM encoded files)")
110 SSL_CMD_ALL(CACertificateFile, TAKE1,
111 "SSL CA Certificate file "
112 "('/path/to/file' - PEM encoded)")
113 SSL_CMD_SRV(CADNRequestPath, TAKE1,
114 "SSL CA Distinguished Name path "
115 "('/path/to/dir' - symlink hashes to PEM of acceptable CA names to request)")
116 SSL_CMD_SRV(CADNRequestFile, TAKE1,
117 "SSL CA Distinguished Name file "
118 "('/path/to/file' - PEM encoded to derive acceptable CA names to request)")
119 SSL_CMD_SRV(CARevocationPath, TAKE1,
120 "SSL CA Certificate Revocation List (CRL) path "
121 "('/path/to/dir' - contains PEM encoded files)")
122 SSL_CMD_SRV(CARevocationFile, TAKE1,
123 "SSL CA Certificate Revocation List (CRL) file "
124 "('/path/to/file' - PEM encoded)")
125 SSL_CMD_SRV(CARevocationCheck, TAKE1,
126 "SSL CA Certificate Revocation List (CRL) checking mode")
127 SSL_CMD_ALL(VerifyClient, TAKE1,
128 "SSL Client verify type "
129 "('none', 'optional', 'require', 'optional_no_ca')")
130 SSL_CMD_ALL(VerifyDepth, TAKE1,
131 "SSL Client verify depth "
132 "('N' - number of intermediate certificates)")
133 SSL_CMD_SRV(SessionCacheTimeout, TAKE1,
134 "SSL Session Cache object lifetime "
135 "('N' - number of seconds)")
137 #define SSL_PROTOCOLS "SSLv3|TLSv1|TLSv1.1|TLSv1.2"
139 #define SSL_PROTOCOLS "SSLv3|TLSv1"
141 SSL_CMD_SRV(Protocol, RAW_ARGS,
142 "Enable or disable various SSL protocols "
143 "('[+-][" SSL_PROTOCOLS "] ...' - see manual)")
144 SSL_CMD_SRV(HonorCipherOrder, FLAG,
145 "Use the server's cipher ordering preference")
146 SSL_CMD_SRV(Compression, FLAG,
147 "Enable SSL level compression "
149 SSL_CMD_SRV(InsecureRenegotiation, FLAG,
150 "Enable support for insecure renegotiation")
151 SSL_CMD_ALL(UserName, TAKE1,
152 "Set user name to SSL variable value")
153 SSL_CMD_SRV(StrictSNIVHostCheck, FLAG,
154 "Strict SNI virtual host checking")
157 SSL_CMD_SRV(SRPVerifierFile, TAKE1,
159 "('/path/to/file' - created by srptool)")
160 SSL_CMD_SRV(SRPUnknownUserSeed, TAKE1,
161 "SRP seed for unknown users (to avoid leaking a user's existence) "
162 "('some secret text')")
166 * Proxy configuration for remote SSL connections
168 SSL_CMD_SRV(ProxyEngine, FLAG,
169 "SSL switch for the proxy protocol engine "
171 SSL_CMD_SRV(ProxyProtocol, RAW_ARGS,
172 "SSL Proxy: enable or disable SSL protocol flavors "
173 "('[+-][" SSL_PROTOCOLS "] ...' - see manual)")
174 SSL_CMD_SRV(ProxyCipherSuite, TAKE1,
175 "SSL Proxy: colon-delimited list of permitted SSL ciphers "
176 "('XXX:...:XXX' - see manual)")
177 SSL_CMD_SRV(ProxyVerify, TAKE1,
178 "SSL Proxy: whether to verify the remote certificate "
180 SSL_CMD_SRV(ProxyVerifyDepth, TAKE1,
181 "SSL Proxy: maximum certificate verification depth "
182 "('N' - number of intermediate certificates)")
183 SSL_CMD_SRV(ProxyCACertificateFile, TAKE1,
184 "SSL Proxy: file containing server certificates "
185 "('/path/to/file' - PEM encoded certificates)")
186 SSL_CMD_SRV(ProxyCACertificatePath, TAKE1,
187 "SSL Proxy: directory containing server certificates "
188 "('/path/to/dir' - contains PEM encoded certificates)")
189 SSL_CMD_SRV(ProxyCARevocationPath, TAKE1,
190 "SSL Proxy: CA Certificate Revocation List (CRL) path "
191 "('/path/to/dir' - contains PEM encoded files)")
192 SSL_CMD_SRV(ProxyCARevocationFile, TAKE1,
193 "SSL Proxy: CA Certificate Revocation List (CRL) file "
194 "('/path/to/file' - PEM encoded)")
195 SSL_CMD_SRV(ProxyCARevocationCheck, TAKE1,
196 "SSL Proxy: CA Certificate Revocation List (CRL) checking mode")
197 SSL_CMD_SRV(ProxyMachineCertificateFile, TAKE1,
198 "SSL Proxy: file containing client certificates "
199 "('/path/to/file' - PEM encoded certificates)")
200 SSL_CMD_SRV(ProxyMachineCertificatePath, TAKE1,
201 "SSL Proxy: directory containing client certificates "
202 "('/path/to/dir' - contains PEM encoded certificates)")
203 SSL_CMD_SRV(ProxyMachineCertificateChainFile, TAKE1,
204 "SSL Proxy: file containing issuing certificates "
205 "of the client certificate "
206 "(`/path/to/file' - PEM encoded certificates)")
207 SSL_CMD_SRV(ProxyCheckPeerExpire, FLAG,
208 "SSL Proxy: check the peer certificate's expiration date")
209 SSL_CMD_SRV(ProxyCheckPeerCN, FLAG,
210 "SSL Proxy: check the peer certificate's CN")
211 SSL_CMD_SRV(ProxyCheckPeerName, FLAG,
212 "SSL Proxy: check the peer certificate's name "
213 "(must be present in subjectAltName extension or CN")
216 * Per-directory context configuration directives
218 SSL_CMD_DIR(Options, OPTIONS, RAW_ARGS,
219 "Set one or more options to configure the SSL engine"
220 "('[+-]option[=value] ...' - see manual)")
221 SSL_CMD_DIR(RequireSSL, AUTHCFG, NO_ARGS,
222 "Require the SSL protocol for the per-directory context "
224 SSL_CMD_DIR(Require, AUTHCFG, RAW_ARGS,
225 "Require a boolean expression to evaluate to true for granting access"
226 "(arbitrary complex boolean expression - see manual)")
227 SSL_CMD_DIR(RenegBufferSize, AUTHCFG, TAKE1,
228 "Configure the amount of memory that will be used for buffering the "
229 "request body if a per-location SSL renegotiation is required due to "
230 "changed access control requirements")
232 SSL_CMD_SRV(OCSPEnable, FLAG,
233 "Enable use of OCSP to verify certificate revocation ('on', 'off')")
234 SSL_CMD_SRV(OCSPDefaultResponder, TAKE1,
235 "URL of the default OCSP Responder")
236 SSL_CMD_SRV(OCSPOverrideResponder, FLAG,
237 "Force use of the default responder URL ('on', 'off')")
238 SSL_CMD_SRV(OCSPResponseTimeSkew, TAKE1,
239 "Maximum time difference in OCSP responses")
240 SSL_CMD_SRV(OCSPResponseMaxAge, TAKE1,
241 "Maximum age of OCSP responses")
242 SSL_CMD_SRV(OCSPResponderTimeout, TAKE1,
243 "OCSP responder query timeout")
245 #ifdef HAVE_OCSP_STAPLING
247 * OCSP Stapling options
249 SSL_CMD_SRV(StaplingCache, TAKE1,
250 "SSL Stapling Response Cache storage "
251 "(`dbm:/path/to/file')")
252 SSL_CMD_SRV(UseStapling, FLAG,
253 "SSL switch for the OCSP Stapling protocol " "(`on', `off')")
254 SSL_CMD_SRV(StaplingResponseTimeSkew, TAKE1,
255 "SSL stapling option for maximum time difference in OCSP responses")
256 SSL_CMD_SRV(StaplingResponderTimeout, TAKE1,
257 "SSL stapling option for OCSP responder timeout")
258 SSL_CMD_SRV(StaplingResponseMaxAge, TAKE1,
259 "SSL stapling option for maximum age of OCSP responses")
260 SSL_CMD_SRV(StaplingStandardCacheTimeout, TAKE1,
261 "SSL stapling option for normal OCSP Response Cache Lifetime")
262 SSL_CMD_SRV(StaplingReturnResponderErrors, FLAG,
263 "SSL stapling switch to return Status Errors Back to Client"
265 SSL_CMD_SRV(StaplingFakeTryLater, FLAG,
266 "SSL stapling switch to send tryLater response to client on error "
268 SSL_CMD_SRV(StaplingErrorCacheTimeout, TAKE1,
269 "SSL stapling option for OCSP Response Error Cache Lifetime")
270 SSL_CMD_SRV(StaplingForceURL, TAKE1,
271 "SSL stapling option to Force the OCSP Stapling URL")
274 #ifdef HAVE_SSL_CONF_CMD
275 SSL_CMD_SRV(OpenSSLConfCmd, TAKE2,
276 "OpenSSL configuration command")
279 /* Deprecated directives. */
280 AP_INIT_RAW_ARGS("SSLLog", ap_set_deprecated, NULL, OR_ALL,
281 "SSLLog directive is no longer supported - use ErrorLog."),
282 AP_INIT_RAW_ARGS("SSLLogLevel", ap_set_deprecated, NULL, OR_ALL,
283 "SSLLogLevel directive is no longer supported - use LogLevel."),
289 * the various processing hooks
291 static apr_status_t ssl_cleanup_pre_config(void *data)
294 * Try to kill the internals of the SSL library.
296 /* Corresponds to OPENSSL_load_builtin_modules():
297 * XXX: borrowed from apps.h, but why not CONF_modules_free()
298 * which also invokes CONF_modules_finish()?
300 CONF_modules_unload(1);
301 /* Corresponds to SSL_library_init: */
303 #if HAVE_ENGINE_LOAD_BUILTIN_ENGINES
306 #if OPENSSL_VERSION_NUMBER >= 0x1000000fL
307 ERR_remove_thread_state(NULL);
312 /* Don't call ERR_free_strings here; ERR_load_*_strings only
313 * actually load the error strings once per process due to static
314 * variable abuse in OpenSSL. */
316 /* Also don't call CRYPTO_cleanup_all_ex_data here; any registered
317 * ex_data indices may have been cached in static variables in
318 * OpenSSL; removing them may cause havoc. Notably, with OpenSSL
319 * versions >= 0.9.8f, COMP_CTX cleanups would not be run, which
320 * could result in a per-connection memory leak (!). */
323 * TODO: determine somewhere we can safely shove out diagnostics
324 * (when enabled) at this late stage in the game:
325 * CRYPTO_mem_leaks_fp(stderr);
330 static int ssl_hook_pre_config(apr_pool_t *pconf,
336 ssl_running_on_valgrind = RUNNING_ON_VALGRIND;
339 /* We must register the library in full, to ensure our configuration
340 * code can successfully test the SSL environment.
342 CRYPTO_malloc_init();
343 ERR_load_crypto_strings();
344 SSL_load_error_strings();
346 #if HAVE_ENGINE_LOAD_BUILTIN_ENGINES
347 ENGINE_load_builtin_engines();
349 OpenSSL_add_all_algorithms();
350 OPENSSL_load_builtin_modules();
353 * Let us cleanup the ssl library when the module is unloaded
355 apr_pool_cleanup_register(pconf, NULL, ssl_cleanup_pre_config,
356 apr_pool_cleanup_null);
358 /* Register us to handle mod_log_config %c/%x variables */
359 ssl_var_log_config_register(pconf);
361 /* Register to handle mod_status status page generation */
362 ssl_scache_status_register(pconf);
364 /* Register mutex type names so they can be configured with Mutex */
365 ap_mutex_register(pconf, SSL_CACHE_MUTEX_TYPE, NULL, APR_LOCK_DEFAULT, 0);
366 #ifdef HAVE_OCSP_STAPLING
367 ap_mutex_register(pconf, SSL_STAPLING_MUTEX_TYPE, NULL, APR_LOCK_DEFAULT, 0);
373 static SSLConnRec *ssl_init_connection_ctx(conn_rec *c)
375 SSLConnRec *sslconn = myConnConfig(c);
381 sslconn = apr_pcalloc(c->pool, sizeof(*sslconn));
383 sslconn->server = c->base_server;
384 sslconn->verify_depth = UNSET;
386 myConnConfigSet(c, sslconn);
391 static int ssl_proxy_enable(conn_rec *c)
395 SSLConnRec *sslconn = ssl_init_connection_ctx(c);
396 sc = mySrvConfig(sslconn->server);
398 if (!sc->proxy_enabled) {
399 ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(01961)
400 "SSL Proxy requested for %s but not enabled "
401 "[Hint: SSLProxyEngine]", sc->vhost_id);
406 sslconn->is_proxy = 1;
407 sslconn->disabled = 0;
412 static int ssl_engine_disable(conn_rec *c)
416 SSLConnRec *sslconn = myConnConfig(c);
419 sc = mySrvConfig(sslconn->server);
422 sc = mySrvConfig(c->base_server);
424 if (sc->enabled == SSL_ENABLED_FALSE) {
428 sslconn = ssl_init_connection_ctx(c);
430 sslconn->disabled = 1;
435 static int modssl_register_npn(conn_rec *c,
436 ssl_npn_advertise_protos advertisefn,
437 ssl_npn_proto_negotiated negotiatedfn)
440 SSLConnRec *sslconn = myConnConfig(c);
446 if (!sslconn->npn_advertfns) {
447 sslconn->npn_advertfns =
448 apr_array_make(c->pool, 5, sizeof(ssl_npn_advertise_protos));
449 sslconn->npn_negofns =
450 apr_array_make(c->pool, 5, sizeof(ssl_npn_proto_negotiated));
454 APR_ARRAY_PUSH(sslconn->npn_advertfns, ssl_npn_advertise_protos) =
457 APR_ARRAY_PUSH(sslconn->npn_negofns, ssl_npn_proto_negotiated) =
466 int ssl_init_ssl_connection(conn_rec *c, request_rec *r)
470 SSLConnRec *sslconn = myConnConfig(c);
476 sslconn = ssl_init_connection_ctx(c);
478 server = sslconn->server;
479 sc = mySrvConfig(server);
482 * Seed the Pseudo Random Number Generator (PRNG)
484 ssl_rand_seed(server, c->pool, SSL_RSCTX_CONNECT, "");
486 mctx = sslconn->is_proxy ? sc->proxy : sc->server;
489 * Create a new SSL connection with the configured server SSL context and
490 * attach this to the socket. Additionally we register this attachment
491 * so we can detach later.
493 if (!(ssl = SSL_new(mctx->ssl_ctx))) {
494 ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(01962)
495 "Unable to create a new SSL connection from the SSL "
497 ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, server);
501 return DECLINED; /* XXX */
504 vhost_md5 = ap_md5_binary(c->pool, (unsigned char *)sc->vhost_id,
507 if (!SSL_set_session_id_context(ssl, (unsigned char *)vhost_md5,
508 APR_MD5_DIGESTSIZE*2))
510 ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c, APLOGNO(01963)
511 "Unable to set session id context to '%s'", vhost_md5);
512 ssl_log_ssl_error(SSLLOG_MARK, APLOG_ERR, server);
516 return DECLINED; /* XXX */
519 SSL_set_app_data(ssl, c);
520 SSL_set_app_data2(ssl, NULL); /* will be request_rec */
524 SSL_set_verify_result(ssl, X509_V_OK);
526 ssl_io_filter_init(c, r, ssl);
531 static const char *ssl_hook_http_scheme(const request_rec *r)
533 SSLSrvConfigRec *sc = mySrvConfig(r->server);
535 if (sc->enabled == SSL_ENABLED_FALSE || sc->enabled == SSL_ENABLED_OPTIONAL) {
542 static apr_port_t ssl_hook_default_port(const request_rec *r)
544 SSLSrvConfigRec *sc = mySrvConfig(r->server);
546 if (sc->enabled == SSL_ENABLED_FALSE || sc->enabled == SSL_ENABLED_OPTIONAL) {
553 static int ssl_hook_pre_connection(conn_rec *c, void *csd)
556 SSLConnRec *sslconn = myConnConfig(c);
559 sc = mySrvConfig(sslconn->server);
562 sc = mySrvConfig(c->base_server);
565 * Immediately stop processing if SSL is disabled for this connection
567 if (!(sc && (sc->enabled == SSL_ENABLED_TRUE ||
568 (sslconn && sslconn->is_proxy))))
577 sslconn = ssl_init_connection_ctx(c);
580 if (sslconn->disabled) {
585 * Remember the connection information for
586 * later access inside callback functions
589 ap_log_cerror(APLOG_MARK, APLOG_INFO, 0, c, APLOGNO(01964)
590 "Connection to child %ld established "
591 "(server %s)", c->id, sc->vhost_id);
593 return ssl_init_ssl_connection(c, NULL);
597 * the module registration phase
600 static void ssl_register_hooks(apr_pool_t *p)
602 /* ssl_hook_ReadReq needs to use the BrowserMatch settings so must
603 * run after mod_setenvif's post_read_request hook. */
604 static const char *pre_prr[] = { "mod_setenvif.c", NULL };
606 ssl_io_filter_register(p);
608 ap_hook_pre_connection(ssl_hook_pre_connection,NULL,NULL, APR_HOOK_MIDDLE);
609 ap_hook_test_config (ssl_hook_ConfigTest, NULL,NULL, APR_HOOK_MIDDLE);
610 ap_hook_post_config (ssl_init_Module, NULL,NULL, APR_HOOK_MIDDLE);
611 ap_hook_http_scheme (ssl_hook_http_scheme, NULL,NULL, APR_HOOK_MIDDLE);
612 ap_hook_default_port (ssl_hook_default_port, NULL,NULL, APR_HOOK_MIDDLE);
613 ap_hook_pre_config (ssl_hook_pre_config, NULL,NULL, APR_HOOK_MIDDLE);
614 ap_hook_child_init (ssl_init_Child, NULL,NULL, APR_HOOK_MIDDLE);
615 ap_hook_check_authn (ssl_hook_UserCheck, NULL,NULL, APR_HOOK_FIRST,
616 AP_AUTH_INTERNAL_PER_CONF);
617 ap_hook_fixups (ssl_hook_Fixup, NULL,NULL, APR_HOOK_MIDDLE);
618 ap_hook_check_access (ssl_hook_Access, NULL,NULL, APR_HOOK_MIDDLE,
619 AP_AUTH_INTERNAL_PER_CONF);
620 ap_hook_check_authz (ssl_hook_Auth, NULL,NULL, APR_HOOK_MIDDLE,
621 AP_AUTH_INTERNAL_PER_CONF);
622 ap_hook_post_read_request(ssl_hook_ReadReq, pre_prr,NULL, APR_HOOK_MIDDLE);
626 APR_REGISTER_OPTIONAL_FN(ssl_proxy_enable);
627 APR_REGISTER_OPTIONAL_FN(ssl_engine_disable);
628 APR_REGISTER_OPTIONAL_FN(modssl_register_npn);
630 ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ssl",
631 AUTHZ_PROVIDER_VERSION,
632 &ssl_authz_provider_require_ssl,
633 AP_AUTH_INTERNAL_PER_CONF);
635 ap_register_auth_provider(p, AUTHZ_PROVIDER_GROUP, "ssl-verify-client",
636 AUTHZ_PROVIDER_VERSION,
637 &ssl_authz_provider_verify_client,
638 AP_AUTH_INTERNAL_PER_CONF);
642 module AP_MODULE_DECLARE_DATA ssl_module = {
643 STANDARD20_MODULE_STUFF,
644 ssl_config_perdir_create, /* create per-dir config structures */
645 ssl_config_perdir_merge, /* merge per-dir config structures */
646 ssl_config_server_create, /* create per-server config structures */
647 ssl_config_server_merge, /* merge per-server config structures */
648 ssl_config_cmds, /* table of configuration directives */
649 ssl_register_hooks /* register hooks */