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 Configuration Directives
26 /* ``Damned if you do,
27 damned if you don't.''
29 #include "ssl_private.h"
30 #include "util_mutex.h"
31 #include "ap_provider.h"
33 /* _________________________________________________________________
35 ** Support for Global Configuration
36 ** _________________________________________________________________
39 #define SSL_MOD_CONFIG_KEY "ssl_module"
41 SSLModConfigRec *ssl_config_global_create(server_rec *s)
43 apr_pool_t *pool = s->process->pool;
47 apr_pool_userdata_get(&vmc, SSL_MOD_CONFIG_KEY, pool);
49 return vmc; /* reused for lifetime of the server */
53 * allocate an own subpool which survives server restarts
55 mc = (SSLModConfigRec *)apr_palloc(pool, sizeof(*mc));
60 * initialize per-module configuration
62 mc->sesscache_mode = SSL_SESS_CACHE_OFF;
65 mc->aRandSeed = apr_array_make(pool, 4,
66 sizeof(ssl_randseed_t));
67 mc->tVHostKeys = apr_hash_make(pool);
68 mc->tPrivateKey = apr_hash_make(pool);
69 mc->tPublicCert = apr_hash_make(pool);
70 #if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
71 mc->szCryptoDevice = NULL;
73 #ifdef HAVE_OCSP_STAPLING
74 mc->stapling_cache = NULL;
75 mc->stapling_mutex = NULL;
78 memset(mc->pTmpKeys, 0, sizeof(mc->pTmpKeys));
80 apr_pool_userdata_set(mc, SSL_MOD_CONFIG_KEY,
81 apr_pool_cleanup_null,
87 void ssl_config_global_fix(SSLModConfigRec *mc)
92 BOOL ssl_config_global_isfixed(SSLModConfigRec *mc)
97 /* _________________________________________________________________
99 ** Configuration handling
100 ** _________________________________________________________________
103 static void modssl_ctx_init(modssl_ctx_t *mctx)
105 mctx->sc = NULL; /* set during module init */
107 mctx->ssl_ctx = NULL; /* set during module init */
112 mctx->protocol = SSL_PROTOCOL_ALL;
114 mctx->pphrase_dialog_type = SSL_PPTYPE_UNSET;
115 mctx->pphrase_dialog_path = NULL;
118 mctx->cert_chain = NULL;
120 mctx->crl_path = NULL;
121 mctx->crl_file = NULL;
122 mctx->crl_check_mode = SSL_CRLCHECK_UNSET;
124 mctx->auth.ca_cert_path = NULL;
125 mctx->auth.ca_cert_file = NULL;
126 mctx->auth.cipher_suite = NULL;
127 mctx->auth.verify_depth = UNSET;
128 mctx->auth.verify_mode = SSL_CVERIFY_UNSET;
130 mctx->ocsp_enabled = FALSE;
131 mctx->ocsp_force_default = FALSE;
132 mctx->ocsp_responder = NULL;
133 mctx->ocsp_resptime_skew = UNSET;
134 mctx->ocsp_resp_maxage = UNSET;
135 mctx->ocsp_responder_timeout = UNSET;
137 #ifdef HAVE_OCSP_STAPLING
138 mctx->stapling_enabled = UNSET;
139 mctx->stapling_resptime_skew = UNSET;
140 mctx->stapling_resp_maxage = UNSET;
141 mctx->stapling_cache_timeout = UNSET;
142 mctx->stapling_return_errors = UNSET;
143 mctx->stapling_fake_trylater = UNSET;
144 mctx->stapling_errcache_timeout = UNSET;
145 mctx->stapling_responder_timeout = UNSET;
146 mctx->stapling_force_url = NULL;
150 static void modssl_ctx_init_proxy(SSLSrvConfigRec *sc,
155 mctx = sc->proxy = apr_palloc(p, sizeof(*sc->proxy));
157 modssl_ctx_init(mctx);
159 mctx->pkp = apr_palloc(p, sizeof(*mctx->pkp));
161 mctx->pkp->cert_file = NULL;
162 mctx->pkp->cert_path = NULL;
163 mctx->pkp->ca_cert_file = NULL;
164 mctx->pkp->certs = NULL;
165 mctx->pkp->ca_certs = NULL;
168 static void modssl_ctx_init_server(SSLSrvConfigRec *sc,
173 mctx = sc->server = apr_palloc(p, sizeof(*sc->server));
175 modssl_ctx_init(mctx);
177 mctx->pks = apr_pcalloc(p, sizeof(*mctx->pks));
179 /* mctx->pks->... certs/keys are set during module init */
182 static SSLSrvConfigRec *ssl_config_server_new(apr_pool_t *p)
184 SSLSrvConfigRec *sc = apr_palloc(p, sizeof(*sc));
187 sc->enabled = SSL_ENABLED_FALSE;
188 sc->proxy_enabled = UNSET;
189 sc->vhost_id = NULL; /* set during module init */
190 sc->vhost_id_len = 0; /* set during module init */
191 sc->session_cache_timeout = UNSET;
192 sc->cipher_server_pref = UNSET;
193 sc->insecure_reneg = UNSET;
194 sc->proxy_ssl_check_peer_expire = SSL_ENABLED_UNSET;
195 sc->proxy_ssl_check_peer_cn = SSL_ENABLED_UNSET;
196 #ifndef OPENSSL_NO_TLSEXT
197 sc->strict_sni_vhost_check = SSL_ENABLED_UNSET;
203 #ifdef HAVE_TLSEXT_TICKETS
204 sc->default_ticket_name = NULL;
205 sc->default_ticket = NULL;
206 sc->tickets = apr_array_make(p, 4, sizeof(modssl_ticket_t*));
209 modssl_ctx_init_proxy(sc, p);
211 modssl_ctx_init_server(sc, p);
217 * Create per-server SSL configuration
219 void *ssl_config_server_create(apr_pool_t *p, server_rec *s)
221 SSLSrvConfigRec *sc = ssl_config_server_new(p);
223 sc->mc = ssl_config_global_create(s);
228 #define cfgMerge(el,unset) mrg->el = (add->el == (unset)) ? base->el : add->el
229 #define cfgMergeArray(el) mrg->el = apr_array_append(p, add->el, base->el)
230 #define cfgMergeString(el) cfgMerge(el, NULL)
231 #define cfgMergeBool(el) cfgMerge(el, UNSET)
232 #define cfgMergeInt(el) cfgMerge(el, UNSET)
234 static void modssl_ctx_cfg_merge(modssl_ctx_t *base,
238 cfgMerge(protocol, SSL_PROTOCOL_ALL);
240 cfgMerge(pphrase_dialog_type, SSL_PPTYPE_UNSET);
241 cfgMergeString(pphrase_dialog_path);
243 cfgMergeString(cert_chain);
245 cfgMerge(crl_path, NULL);
246 cfgMerge(crl_file, NULL);
247 cfgMerge(crl_check_mode, SSL_CRLCHECK_UNSET);
249 cfgMergeString(auth.ca_cert_path);
250 cfgMergeString(auth.ca_cert_file);
251 cfgMergeString(auth.cipher_suite);
252 cfgMergeInt(auth.verify_depth);
253 cfgMerge(auth.verify_mode, SSL_CVERIFY_UNSET);
255 cfgMergeBool(ocsp_enabled);
256 cfgMergeBool(ocsp_force_default);
257 cfgMerge(ocsp_responder, NULL);
258 cfgMergeInt(ocsp_resptime_skew);
259 cfgMergeInt(ocsp_resp_maxage);
260 cfgMergeInt(ocsp_responder_timeout);
261 #ifdef HAVE_OCSP_STAPLING
262 cfgMergeBool(stapling_enabled);
263 cfgMergeInt(stapling_resptime_skew);
264 cfgMergeInt(stapling_resp_maxage);
265 cfgMergeInt(stapling_cache_timeout);
266 cfgMergeBool(stapling_return_errors);
267 cfgMergeBool(stapling_fake_trylater);
268 cfgMergeInt(stapling_errcache_timeout);
269 cfgMergeInt(stapling_responder_timeout);
270 cfgMerge(stapling_force_url, NULL);
274 static void modssl_ctx_cfg_merge_proxy(modssl_ctx_t *base,
278 modssl_ctx_cfg_merge(base, add, mrg);
280 cfgMergeString(pkp->cert_file);
281 cfgMergeString(pkp->cert_path);
282 cfgMergeString(pkp->ca_cert_file);
285 static void modssl_ctx_cfg_merge_server(modssl_ctx_t *base,
291 modssl_ctx_cfg_merge(base, add, mrg);
293 for (i = 0; i < SSL_AIDX_MAX; i++) {
294 cfgMergeString(pks->cert_files[i]);
295 cfgMergeString(pks->key_files[i]);
298 cfgMergeString(pks->ca_name_path);
299 cfgMergeString(pks->ca_name_file);
303 * Merge per-server SSL configurations
305 void *ssl_config_server_merge(apr_pool_t *p, void *basev, void *addv)
307 SSLSrvConfigRec *base = (SSLSrvConfigRec *)basev;
308 SSLSrvConfigRec *add = (SSLSrvConfigRec *)addv;
309 SSLSrvConfigRec *mrg = ssl_config_server_new(p);
312 cfgMerge(enabled, SSL_ENABLED_UNSET);
313 #ifdef HAVE_TLSEXT_TICKETS
314 cfgMergeString(default_ticket_name);
315 apr_array_cat(mrg->tickets, base->tickets);
316 apr_array_cat(mrg->tickets, add->tickets);
318 cfgMergeBool(proxy_enabled);
319 cfgMergeInt(session_cache_timeout);
320 cfgMergeBool(cipher_server_pref);
321 cfgMergeBool(insecure_reneg);
322 cfgMerge(proxy_ssl_check_peer_expire, SSL_ENABLED_UNSET);
323 cfgMerge(proxy_ssl_check_peer_cn, SSL_ENABLED_UNSET);
324 #ifndef OPENSSL_NO_TLSEXT
325 cfgMerge(strict_sni_vhost_check, SSL_ENABLED_UNSET);
331 modssl_ctx_cfg_merge_proxy(base->proxy, add->proxy, mrg->proxy);
333 modssl_ctx_cfg_merge_server(base->server, add->server, mrg->server);
339 * Create per-directory SSL configuration
341 void *ssl_config_perdir_create(apr_pool_t *p, char *dir)
343 SSLDirConfigRec *dc = apr_palloc(p, sizeof(*dc));
345 dc->bSSLRequired = FALSE;
346 dc->aRequirement = apr_array_make(p, 4, sizeof(ssl_require_t));
347 dc->nOptions = SSL_OPT_NONE|SSL_OPT_RELSET;
348 dc->nOptionsAdd = SSL_OPT_NONE;
349 dc->nOptionsDel = SSL_OPT_NONE;
351 dc->szCipherSuite = NULL;
352 dc->nVerifyClient = SSL_CVERIFY_UNSET;
353 dc->nVerifyDepth = UNSET;
355 dc->szCACertificatePath = NULL;
356 dc->szCACertificateFile = NULL;
357 dc->szUserName = NULL;
359 dc->nRenegBufferSize = UNSET;
365 * Merge per-directory SSL configurations
367 void *ssl_config_perdir_merge(apr_pool_t *p, void *basev, void *addv)
369 SSLDirConfigRec *base = (SSLDirConfigRec *)basev;
370 SSLDirConfigRec *add = (SSLDirConfigRec *)addv;
371 SSLDirConfigRec *mrg = (SSLDirConfigRec *)apr_palloc(p, sizeof(*mrg));
373 cfgMerge(bSSLRequired, FALSE);
374 cfgMergeArray(aRequirement);
376 if (add->nOptions & SSL_OPT_RELSET) {
378 (base->nOptionsAdd & ~(add->nOptionsDel)) | add->nOptionsAdd;
380 (base->nOptionsDel & ~(add->nOptionsAdd)) | add->nOptionsDel;
382 (base->nOptions & ~(mrg->nOptionsDel)) | mrg->nOptionsAdd;
385 mrg->nOptions = add->nOptions;
386 mrg->nOptionsAdd = add->nOptionsAdd;
387 mrg->nOptionsDel = add->nOptionsDel;
390 cfgMergeString(szCipherSuite);
391 cfgMerge(nVerifyClient, SSL_CVERIFY_UNSET);
392 cfgMergeInt(nVerifyDepth);
394 cfgMergeString(szCACertificatePath);
395 cfgMergeString(szCACertificateFile);
396 cfgMergeString(szUserName);
398 cfgMergeInt(nRenegBufferSize);
404 * Configuration functions for particular directives
407 const char *ssl_cmd_SSLPassPhraseDialog(cmd_parms *cmd,
411 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
413 int arglen = strlen(arg);
415 if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
419 if (strcEQ(arg, "builtin")) {
420 sc->server->pphrase_dialog_type = SSL_PPTYPE_BUILTIN;
421 sc->server->pphrase_dialog_path = NULL;
423 else if ((arglen > 5) && strEQn(arg, "exec:", 5)) {
424 sc->server->pphrase_dialog_type = SSL_PPTYPE_FILTER;
425 sc->server->pphrase_dialog_path =
426 ap_server_root_relative(cmd->pool, arg+5);
427 if (!sc->server->pphrase_dialog_path) {
428 return apr_pstrcat(cmd->pool,
429 "Invalid SSLPassPhraseDialog exec: path ",
432 if (!ssl_util_path_check(SSL_PCM_EXISTS,
433 sc->server->pphrase_dialog_path,
436 return apr_pstrcat(cmd->pool,
437 "SSLPassPhraseDialog: file '",
438 sc->server->pphrase_dialog_path,
439 "' does not exist", NULL);
443 else if ((arglen > 1) && (arg[0] == '|')) {
444 sc->server->pphrase_dialog_type = SSL_PPTYPE_PIPE;
445 sc->server->pphrase_dialog_path = arg + 1;
448 return "SSLPassPhraseDialog: Invalid argument";
454 #if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
455 const char *ssl_cmd_SSLCryptoDevice(cmd_parms *cmd,
459 SSLModConfigRec *mc = myModConfig(cmd->server);
463 if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
467 if (strcEQ(arg, "builtin")) {
468 mc->szCryptoDevice = NULL;
470 else if ((e = ENGINE_by_id(arg))) {
471 mc->szCryptoDevice = arg;
475 err = "SSLCryptoDevice: Invalid argument; must be one of: "
477 e = ENGINE_get_first();
479 err = apr_pstrcat(cmd->pool, err, ", '", ENGINE_get_id(e),
480 "' (", ENGINE_get_name(e), ")", NULL);
481 /* Iterate; this call implicitly decrements the refcount
482 * on the 'old' e, per the docs in engine.h. */
483 e = ENGINE_get_next(e);
492 const char *ssl_cmd_SSLRandomSeed(cmd_parms *cmd,
498 SSLModConfigRec *mc = myModConfig(cmd->server);
500 ssl_randseed_t *seed;
501 int arg2len = strlen(arg2);
503 if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
507 if (ssl_config_global_isfixed(mc)) {
511 seed = apr_array_push(mc->aRandSeed);
513 if (strcEQ(arg1, "startup")) {
514 seed->nCtx = SSL_RSCTX_STARTUP;
516 else if (strcEQ(arg1, "connect")) {
517 seed->nCtx = SSL_RSCTX_CONNECT;
520 return apr_pstrcat(cmd->pool, "SSLRandomSeed: "
521 "invalid context: `", arg1, "'",
525 if ((arg2len > 5) && strEQn(arg2, "file:", 5)) {
526 seed->nSrc = SSL_RSSRC_FILE;
527 seed->cpPath = ap_server_root_relative(mc->pPool, arg2+5);
529 else if ((arg2len > 5) && strEQn(arg2, "exec:", 5)) {
530 seed->nSrc = SSL_RSSRC_EXEC;
531 seed->cpPath = ap_server_root_relative(mc->pPool, arg2+5);
533 else if ((arg2len > 4) && strEQn(arg2, "egd:", 4)) {
534 seed->nSrc = SSL_RSSRC_EGD;
535 seed->cpPath = ap_server_root_relative(mc->pPool, arg2+4);
537 else if (strcEQ(arg2, "builtin")) {
538 seed->nSrc = SSL_RSSRC_BUILTIN;
542 seed->nSrc = SSL_RSSRC_FILE;
543 seed->cpPath = ap_server_root_relative(mc->pPool, arg2);
546 if (seed->nSrc != SSL_RSSRC_BUILTIN) {
548 return apr_pstrcat(cmd->pool,
549 "Invalid SSLRandomSeed path ",
552 if (!ssl_util_path_check(SSL_PCM_EXISTS, seed->cpPath, cmd->pool)) {
553 return apr_pstrcat(cmd->pool,
554 "SSLRandomSeed: source path '",
555 seed->cpPath, "' does not exist", NULL);
560 seed->nBytes = 0; /* read whole file */
563 if (seed->nSrc == SSL_RSSRC_BUILTIN) {
564 return "SSLRandomSeed: byte specification not "
565 "allowed for builtin seed source";
568 seed->nBytes = atoi(arg3);
570 if (seed->nBytes < 0) {
571 return "SSLRandomSeed: invalid number of bytes specified";
578 const char *ssl_cmd_SSLEngine(cmd_parms *cmd, void *dcfg, const char *arg)
580 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
582 if (!strcasecmp(arg, "On")) {
583 sc->enabled = SSL_ENABLED_TRUE;
586 else if (!strcasecmp(arg, "Off")) {
587 sc->enabled = SSL_ENABLED_FALSE;
590 else if (!strcasecmp(arg, "Optional")) {
591 sc->enabled = SSL_ENABLED_OPTIONAL;
595 return "Argument must be On, Off, or Optional";
598 const char *ssl_cmd_SSLTicketKeyDefault(cmd_parms *cmd, void *dcfg, const char *name)
600 #ifdef HAVE_TLSEXT_TICKETS
601 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
603 sc->default_ticket_name = name;
607 return "TLS Ticket keys are not supported.";
611 const char *ssl_cmd_SSLTicketKeyFile(cmd_parms *cmd, void *dcfg, const char *name, const char *path)
613 #ifdef HAVE_TLSEXT_TICKETS
617 char buf[TLSEXT_TICKET_KEYLEN];
618 modssl_ticket_t* ticket = NULL;
619 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
621 path = ap_server_root_relative(cmd->pool, path);
623 rv = apr_file_open(&fp, path, APR_READ|APR_BINARY,
624 APR_OS_DEFAULT, cmd->temp_pool);
626 if (rv != APR_SUCCESS) {
627 return apr_psprintf(cmd->pool,
628 "Failed to open %s: (%d) %pm",
632 rv = apr_file_read_full(fp, &buf[0], TLSEXT_TICKET_KEYLEN, &len);
634 if (rv != APR_SUCCESS) {
635 return apr_psprintf(cmd->pool,
636 "Failed to read at least 48 bytes from %s: (%d) %pm",
640 ticket = apr_palloc(cmd->pool, sizeof(modssl_ticket_t));
642 ticket->conf_name = name;
644 memcpy(ticket->key_name, buf, 16);
645 memcpy(ticket->hmac_secret, buf + 16, 16);
646 memcpy(ticket->aes_key, buf + 32, 16);
648 APR_ARRAY_PUSH(sc->tickets, modssl_ticket_t*) = ticket;
652 return "TLS Ticket keys are not supported.";
656 const char *ssl_cmd_SSLFIPS(cmd_parms *cmd, void *dcfg, int flag)
659 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
663 if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
668 if ((sc->fips != UNSET) && (sc->fips != (BOOL)(flag ? TRUE : FALSE)))
669 return "Conflicting SSLFIPS options, cannot be both On and Off";
670 sc->fips = flag ? TRUE : FALSE;
673 return "SSLFIPS invalid, rebuild httpd and openssl compiled for FIPS";
679 const char *ssl_cmd_SSLCipherSuite(cmd_parms *cmd,
683 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
684 SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
687 dc->szCipherSuite = arg;
690 sc->server->auth.cipher_suite = arg;
696 #define SSL_FLAGS_CHECK_FILE \
697 (SSL_PCM_EXISTS|SSL_PCM_ISREG|SSL_PCM_ISNONZERO)
699 #define SSL_FLAGS_CHECK_DIR \
700 (SSL_PCM_EXISTS|SSL_PCM_ISDIR)
702 static const char *ssl_cmd_check_file(cmd_parms *parms,
705 const char *filepath = ap_server_root_relative(parms->pool, *file);
708 return apr_pstrcat(parms->pool, parms->cmd->name,
709 ": Invalid file path ", *file, NULL);
713 if (ssl_util_path_check(SSL_FLAGS_CHECK_FILE, *file, parms->pool)) {
717 return apr_pstrcat(parms->pool, parms->cmd->name,
719 "' does not exist or is empty", NULL);
723 const char *ssl_cmd_SSLHonorCipherOrder(cmd_parms *cmd, void *dcfg, int flag)
725 #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
726 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
727 sc->cipher_server_pref = flag?TRUE:FALSE;
730 return "SSLHonorCiperOrder unsupported; not implemented by the SSL library";
734 const char *ssl_cmd_SSLInsecureRenegotiation(cmd_parms *cmd, void *dcfg, int flag)
736 #ifdef SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION
737 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
738 sc->insecure_reneg = flag?TRUE:FALSE;
741 return "The SSLInsecureRenegotiation directive is not available "
742 "with this SSL library";
747 static const char *ssl_cmd_check_dir(cmd_parms *parms,
750 const char *dirpath = ap_server_root_relative(parms->pool, *dir);
753 return apr_pstrcat(parms->pool, parms->cmd->name,
754 ": Invalid dir path ", *dir, NULL);
758 if (ssl_util_path_check(SSL_FLAGS_CHECK_DIR, *dir, parms->pool)) {
762 return apr_pstrcat(parms->pool, parms->cmd->name,
763 ": directory '", *dir,
764 "' does not exist", NULL);
768 #define SSL_AIDX_CERTS 1
769 #define SSL_AIDX_KEYS 2
771 static const char *ssl_cmd_check_aidx_max(cmd_parms *parms,
775 SSLSrvConfigRec *sc = mySrvConfig(parms->server);
776 const char *err, *desc=NULL, **files=NULL;
779 if ((err = ssl_cmd_check_file(parms, &arg))) {
785 desc = "certificates";
786 files = sc->server->pks->cert_files;
789 desc = "private keys";
790 files = sc->server->pks->key_files;
794 for (i = 0; i < SSL_AIDX_MAX; i++) {
801 return apr_psprintf(parms->pool,
803 "different %s per virtual host allowed",
804 parms->cmd->name, SSL_AIDX_MAX, desc);
807 const char *ssl_cmd_SSLCertificateFile(cmd_parms *cmd,
814 if ((err = ssl_cmd_check_aidx_max(cmd, arg, SSL_AIDX_CERTS))) {
821 const char *ssl_cmd_SSLCertificateKeyFile(cmd_parms *cmd,
827 if ((err = ssl_cmd_check_aidx_max(cmd, arg, SSL_AIDX_KEYS))) {
834 const char *ssl_cmd_SSLCertificateChainFile(cmd_parms *cmd,
838 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
841 if ((err = ssl_cmd_check_file(cmd, &arg))) {
845 sc->server->cert_chain = arg;
850 const char *ssl_cmd_SSLPKCS7CertificateFile(cmd_parms *cmd,
854 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
857 if ((err = ssl_cmd_check_file(cmd, &arg))) {
861 sc->server->pkcs7 = arg;
866 #define NO_PER_DIR_SSL_CA \
867 "Your SSL library does not have support for per-directory CA"
869 const char *ssl_cmd_SSLCACertificatePath(cmd_parms *cmd,
873 /*SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;*/
874 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
877 if ((err = ssl_cmd_check_dir(cmd, &arg))) {
882 return NO_PER_DIR_SSL_CA;
885 /* XXX: bring back per-dir */
886 sc->server->auth.ca_cert_path = arg;
891 const char *ssl_cmd_SSLCACertificateFile(cmd_parms *cmd,
895 /*SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;*/
896 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
899 if ((err = ssl_cmd_check_file(cmd, &arg))) {
904 return NO_PER_DIR_SSL_CA;
907 /* XXX: bring back per-dir */
908 sc->server->auth.ca_cert_file = arg;
913 const char *ssl_cmd_SSLCADNRequestPath(cmd_parms *cmd, void *dcfg,
916 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
919 if ((err = ssl_cmd_check_dir(cmd, &arg))) {
923 sc->server->pks->ca_name_path = arg;
928 const char *ssl_cmd_SSLCADNRequestFile(cmd_parms *cmd, void *dcfg,
931 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
934 if ((err = ssl_cmd_check_file(cmd, &arg))) {
938 sc->server->pks->ca_name_file = arg;
943 const char *ssl_cmd_SSLCARevocationPath(cmd_parms *cmd,
947 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
950 if ((err = ssl_cmd_check_dir(cmd, &arg))) {
954 sc->server->crl_path = arg;
959 const char *ssl_cmd_SSLCARevocationFile(cmd_parms *cmd,
963 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
966 if ((err = ssl_cmd_check_file(cmd, &arg))) {
970 sc->server->crl_file = arg;
975 static const char *ssl_cmd_crlcheck_parse(cmd_parms *parms,
977 ssl_crlcheck_t *mode)
979 if (strcEQ(arg, "none")) {
980 *mode = SSL_CRLCHECK_NONE;
982 else if (strcEQ(arg, "leaf")) {
983 *mode = SSL_CRLCHECK_LEAF;
985 else if (strcEQ(arg, "chain")) {
986 *mode = SSL_CRLCHECK_CHAIN;
989 return apr_pstrcat(parms->temp_pool, parms->cmd->name,
990 ": Invalid argument '", arg, "'",
997 const char *ssl_cmd_SSLCARevocationCheck(cmd_parms *cmd,
1001 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1003 return ssl_cmd_crlcheck_parse(cmd, arg, &sc->server->crl_check_mode);
1006 static const char *ssl_cmd_verify_parse(cmd_parms *parms,
1010 if (strcEQ(arg, "none") || strcEQ(arg, "off")) {
1011 *id = SSL_CVERIFY_NONE;
1013 else if (strcEQ(arg, "optional")) {
1014 *id = SSL_CVERIFY_OPTIONAL;
1016 else if (strcEQ(arg, "require") || strcEQ(arg, "on")) {
1017 *id = SSL_CVERIFY_REQUIRE;
1019 else if (strcEQ(arg, "optional_no_ca")) {
1020 *id = SSL_CVERIFY_OPTIONAL_NO_CA;
1023 return apr_pstrcat(parms->temp_pool, parms->cmd->name,
1024 ": Invalid argument '", arg, "'",
1031 const char *ssl_cmd_SSLVerifyClient(cmd_parms *cmd,
1035 SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
1036 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1040 if ((err = ssl_cmd_verify_parse(cmd, arg, &mode))) {
1045 dc->nVerifyClient = mode;
1048 sc->server->auth.verify_mode = mode;
1054 static const char *ssl_cmd_verify_depth_parse(cmd_parms *parms,
1058 if ((*depth = atoi(arg)) >= 0) {
1062 return apr_pstrcat(parms->temp_pool, parms->cmd->name,
1063 ": Invalid argument '", arg, "'",
1067 const char *ssl_cmd_SSLVerifyDepth(cmd_parms *cmd,
1071 SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
1072 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1076 if ((err = ssl_cmd_verify_depth_parse(cmd, arg, &depth))) {
1081 dc->nVerifyDepth = depth;
1084 sc->server->auth.verify_depth = depth;
1090 const char *ssl_cmd_SSLSessionCache(cmd_parms *cmd,
1094 SSLModConfigRec *mc = myModConfig(cmd->server);
1095 const char *err, *sep, *name;
1098 if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
1102 /* The OpenSSL session cache mode must have both the flags
1103 * SSL_SESS_CACHE_SERVER and SSL_SESS_CACHE_NO_INTERNAL set if a
1104 * session cache is configured; NO_INTERNAL prevents the
1105 * OpenSSL-internal session cache being used in addition to the
1106 * "external" (mod_ssl-provided) cache, which otherwise causes
1107 * additional memory consumption. */
1108 enabled_flags = SSL_SESS_CACHE_SERVER | SSL_SESS_CACHE_NO_INTERNAL;
1110 if (strcEQ(arg, "none")) {
1111 /* Nothing to do; session cache will be off. */
1113 else if (strcEQ(arg, "nonenotnull")) {
1114 /* ### Having a separate mode for this seems logically
1115 * unnecessary; the stated purpose of sending non-empty
1116 * session IDs would be better fixed in OpenSSL or simply
1117 * doing it by default if "none" is used. */
1118 mc->sesscache_mode = enabled_flags;
1121 /* Argument is of form 'name:args' or just 'name'. */
1122 sep = ap_strchr_c(arg, ':');
1124 name = apr_pstrmemdup(cmd->pool, arg, sep - arg);
1131 /* Find the provider of given name. */
1132 mc->sesscache = ap_lookup_provider(AP_SOCACHE_PROVIDER_GROUP,
1134 AP_SOCACHE_PROVIDER_VERSION);
1135 if (mc->sesscache) {
1136 /* Cache found; create it, passing anything beyond the colon. */
1137 mc->sesscache_mode = enabled_flags;
1138 err = mc->sesscache->create(&mc->sesscache_context, sep,
1139 cmd->temp_pool, cmd->pool);
1142 apr_array_header_t *name_list;
1143 const char *all_names;
1145 /* Build a comma-separated list of all registered provider
1147 name_list = ap_list_provider_names(cmd->pool,
1148 AP_SOCACHE_PROVIDER_GROUP,
1149 AP_SOCACHE_PROVIDER_VERSION);
1150 all_names = apr_array_pstrcat(cmd->pool, name_list, ',');
1152 err = apr_psprintf(cmd->pool, "'%s' session cache not supported "
1153 "(known names: %s)", name, all_names);
1158 return apr_psprintf(cmd->pool, "SSLSessionCache: %s", err);
1164 const char *ssl_cmd_SSLSessionCacheTimeout(cmd_parms *cmd,
1168 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1170 sc->session_cache_timeout = atoi(arg);
1172 if (sc->session_cache_timeout < 0) {
1173 return "SSLSessionCacheTimeout: Invalid argument";
1179 const char *ssl_cmd_SSLOptions(cmd_parms *cmd,
1183 SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
1189 w = ap_getword_conf(cmd->temp_pool, &arg);
1192 if ((*w == '+') || (*w == '-')) {
1196 dc->nOptions = SSL_OPT_NONE;
1200 if (strcEQ(w, "StdEnvVars")) {
1201 opt = SSL_OPT_STDENVVARS;
1203 else if (strcEQ(w, "ExportCertData")) {
1204 opt = SSL_OPT_EXPORTCERTDATA;
1206 else if (strcEQ(w, "FakeBasicAuth")) {
1207 opt = SSL_OPT_FAKEBASICAUTH;
1209 else if (strcEQ(w, "StrictRequire")) {
1210 opt = SSL_OPT_STRICTREQUIRE;
1212 else if (strcEQ(w, "OptRenegotiate")) {
1213 opt = SSL_OPT_OPTRENEGOTIATE;
1215 else if (strcEQ(w, "LegacyDNStringFormat")) {
1216 opt = SSL_OPT_LEGACYDNFORMAT;
1219 return apr_pstrcat(cmd->pool,
1220 "SSLOptions: Illegal option '", w, "'",
1224 if (action == '-') {
1225 dc->nOptionsAdd &= ~opt;
1226 dc->nOptionsDel |= opt;
1227 dc->nOptions &= ~opt;
1229 else if (action == '+') {
1230 dc->nOptionsAdd |= opt;
1231 dc->nOptionsDel &= ~opt;
1232 dc->nOptions |= opt;
1236 dc->nOptionsAdd = opt;
1237 dc->nOptionsDel = SSL_OPT_NONE;
1244 const char *ssl_cmd_SSLRequireSSL(cmd_parms *cmd, void *dcfg)
1246 SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
1248 dc->bSSLRequired = TRUE;
1253 const char *ssl_cmd_SSLRequire(cmd_parms *cmd,
1257 SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
1258 ap_expr_info_t *info = apr_pcalloc(cmd->pool, sizeof(ap_expr_info_t));
1259 ssl_require_t *require;
1260 const char *errstring;
1262 info->flags = AP_EXPR_FLAG_SSL_EXPR_COMPAT;
1263 info->filename = cmd->directive->filename;
1264 info->line_number = cmd->directive->line_num;
1265 info->module_index = APLOG_MODULE_INDEX;
1266 errstring = ap_expr_parse(cmd->pool, cmd->temp_pool, info, arg, NULL);
1268 return apr_pstrcat(cmd->pool, "SSLRequire: ", errstring, NULL);
1271 require = apr_array_push(dc->aRequirement);
1272 require->cpExpr = apr_pstrdup(cmd->pool, arg);
1273 require->mpExpr = info;
1278 const char *ssl_cmd_SSLRenegBufferSize(cmd_parms *cmd, void *dcfg, const char *arg)
1280 SSLDirConfigRec *dc = dcfg;
1285 return apr_pstrcat(cmd->pool, "Invalid size for SSLRenegBufferSize: ",
1288 dc->nRenegBufferSize = val;
1293 static const char *ssl_cmd_protocol_parse(cmd_parms *parms,
1295 ssl_proto_t *options)
1297 ssl_proto_t thisopt;
1299 *options = SSL_PROTOCOL_NONE;
1302 char *w = ap_getword_conf(parms->temp_pool, &arg);
1305 if ((*w == '+') || (*w == '-')) {
1309 if (strcEQ(w, "SSLv2")) {
1310 if (action == '-') {
1314 return "SSLProtocol: SSLv2 is no longer supported";
1317 else if (strcEQ(w, "SSLv3")) {
1318 thisopt = SSL_PROTOCOL_SSLV3;
1320 else if (strcEQ(w, "TLSv1")) {
1321 thisopt = SSL_PROTOCOL_TLSV1;
1323 else if (strcEQ(w, "all")) {
1324 thisopt = SSL_PROTOCOL_ALL;
1327 return apr_pstrcat(parms->temp_pool,
1329 ": Illegal protocol '",
1333 if (action == '-') {
1334 *options &= ~thisopt;
1336 else if (action == '+') {
1337 *options |= thisopt;
1347 const char *ssl_cmd_SSLProtocol(cmd_parms *cmd,
1351 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1353 return ssl_cmd_protocol_parse(cmd, arg, &sc->server->protocol);
1356 const char *ssl_cmd_SSLProxyEngine(cmd_parms *cmd, void *dcfg, int flag)
1358 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1360 sc->proxy_enabled = flag ? TRUE : FALSE;
1365 const char *ssl_cmd_SSLProxyProtocol(cmd_parms *cmd,
1369 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1371 return ssl_cmd_protocol_parse(cmd, arg, &sc->proxy->protocol);
1374 const char *ssl_cmd_SSLProxyCipherSuite(cmd_parms *cmd,
1378 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1380 sc->proxy->auth.cipher_suite = arg;
1385 const char *ssl_cmd_SSLProxyVerify(cmd_parms *cmd,
1389 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1393 if ((err = ssl_cmd_verify_parse(cmd, arg, &mode))) {
1397 sc->proxy->auth.verify_mode = mode;
1402 const char *ssl_cmd_SSLProxyVerifyDepth(cmd_parms *cmd,
1406 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1410 if ((err = ssl_cmd_verify_depth_parse(cmd, arg, &depth))) {
1414 sc->proxy->auth.verify_depth = depth;
1419 const char *ssl_cmd_SSLProxyCACertificateFile(cmd_parms *cmd,
1423 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1426 if ((err = ssl_cmd_check_file(cmd, &arg))) {
1430 sc->proxy->auth.ca_cert_file = arg;
1435 const char *ssl_cmd_SSLProxyCACertificatePath(cmd_parms *cmd,
1439 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1442 if ((err = ssl_cmd_check_dir(cmd, &arg))) {
1446 sc->proxy->auth.ca_cert_path = arg;
1451 const char *ssl_cmd_SSLProxyCARevocationPath(cmd_parms *cmd,
1455 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1458 if ((err = ssl_cmd_check_dir(cmd, &arg))) {
1462 sc->proxy->crl_path = arg;
1467 const char *ssl_cmd_SSLProxyCARevocationFile(cmd_parms *cmd,
1471 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1474 if ((err = ssl_cmd_check_file(cmd, &arg))) {
1478 sc->proxy->crl_file = arg;
1483 const char *ssl_cmd_SSLProxyCARevocationCheck(cmd_parms *cmd,
1487 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1489 return ssl_cmd_crlcheck_parse(cmd, arg, &sc->proxy->crl_check_mode);
1492 const char *ssl_cmd_SSLProxyMachineCertificateFile(cmd_parms *cmd,
1496 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1499 if ((err = ssl_cmd_check_file(cmd, &arg))) {
1503 sc->proxy->pkp->cert_file = arg;
1508 const char *ssl_cmd_SSLProxyMachineCertificatePath(cmd_parms *cmd,
1512 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1515 if ((err = ssl_cmd_check_dir(cmd, &arg))) {
1519 sc->proxy->pkp->cert_path = arg;
1524 const char *ssl_cmd_SSLProxyMachineCertificateChainFile(cmd_parms *cmd,
1528 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1531 if ((err = ssl_cmd_check_file(cmd, &arg))) {
1535 sc->proxy->pkp->ca_cert_file = arg;
1540 const char *ssl_cmd_SSLUserName(cmd_parms *cmd, void *dcfg,
1543 SSLDirConfigRec *dc = (SSLDirConfigRec *)dcfg;
1544 dc->szUserName = arg;
1548 const char *ssl_cmd_SSLOCSPEnable(cmd_parms *cmd, void *dcfg, int flag)
1550 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1552 sc->server->ocsp_enabled = flag ? TRUE : FALSE;
1554 #ifdef OPENSSL_NO_OCSP
1556 return "OCSP support disabled in SSL library; cannot enable "
1564 const char *ssl_cmd_SSLOCSPOverrideResponder(cmd_parms *cmd, void *dcfg, int flag)
1566 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1568 sc->server->ocsp_force_default = flag ? TRUE : FALSE;
1573 const char *ssl_cmd_SSLOCSPDefaultResponder(cmd_parms *cmd, void *dcfg, const char *arg)
1575 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1577 sc->server->ocsp_responder = arg;
1582 const char *ssl_cmd_SSLOCSPResponseTimeSkew(cmd_parms *cmd, void *dcfg, const char *arg)
1584 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1585 sc->server->ocsp_resptime_skew = atoi(arg);
1586 if (sc->server->ocsp_resptime_skew < 0) {
1587 return "SSLOCSPResponseTimeSkew: invalid argument";
1592 const char *ssl_cmd_SSLOCSPResponseMaxAge(cmd_parms *cmd, void *dcfg, const char *arg)
1594 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1595 sc->server->ocsp_resp_maxage = atoi(arg);
1596 if (sc->server->ocsp_resp_maxage < 0) {
1597 return "SSLOCSPResponseMaxAge: invalid argument";
1602 const char *ssl_cmd_SSLOCSPResponderTimeout(cmd_parms *cmd, void *dcfg, const char *arg)
1604 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1605 sc->server->ocsp_responder_timeout = apr_time_from_sec(atoi(arg));
1606 if (sc->server->ocsp_responder_timeout < 0) {
1607 return "SSLOCSPResponderTimeout: invalid argument";
1612 const char *ssl_cmd_SSLProxyCheckPeerExpire(cmd_parms *cmd, void *dcfg, int flag)
1614 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1616 sc->proxy_ssl_check_peer_expire = flag ? SSL_ENABLED_TRUE : SSL_ENABLED_FALSE;
1621 const char *ssl_cmd_SSLProxyCheckPeerCN(cmd_parms *cmd, void *dcfg, int flag)
1623 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1625 sc->proxy_ssl_check_peer_cn = flag ? SSL_ENABLED_TRUE : SSL_ENABLED_FALSE;
1630 const char *ssl_cmd_SSLStrictSNIVHostCheck(cmd_parms *cmd, void *dcfg, int flag)
1632 #ifndef OPENSSL_NO_TLSEXT
1633 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1635 sc->strict_sni_vhost_check = flag ? SSL_ENABLED_TRUE : SSL_ENABLED_FALSE;
1639 return "SSLStrictSNIVHostCheck failed; OpenSSL is not built with support "
1640 "for TLS extensions and SNI indication. Refer to the "
1641 "documentation, and build a compatible version of OpenSSL.";
1645 #ifdef HAVE_OCSP_STAPLING
1647 const char *ssl_cmd_SSLStaplingCache(cmd_parms *cmd,
1651 SSLModConfigRec *mc = myModConfig(cmd->server);
1652 const char *err, *sep, *name;
1654 if ((err = ap_check_cmd_context(cmd, GLOBAL_ONLY))) {
1658 /* Argument is of form 'name:args' or just 'name'. */
1659 sep = ap_strchr_c(arg, ':');
1661 name = apr_pstrmemdup(cmd->pool, arg, sep - arg);
1668 /* Find the provider of given name. */
1669 mc->stapling_cache = ap_lookup_provider(AP_SOCACHE_PROVIDER_GROUP,
1671 AP_SOCACHE_PROVIDER_VERSION);
1672 if (mc->stapling_cache) {
1673 /* Cache found; create it, passing anything beyond the colon. */
1674 err = mc->stapling_cache->create(&mc->stapling_cache_context,
1675 sep, cmd->temp_pool,
1679 apr_array_header_t *name_list;
1680 const char *all_names;
1682 /* Build a comma-separated list of all registered provider
1684 name_list = ap_list_provider_names(cmd->pool,
1685 AP_SOCACHE_PROVIDER_GROUP,
1686 AP_SOCACHE_PROVIDER_VERSION);
1687 all_names = apr_array_pstrcat(cmd->pool, name_list, ',');
1689 err = apr_psprintf(cmd->pool, "'%s' stapling cache not supported "
1690 "(known names: %s)", name, all_names);
1694 return apr_psprintf(cmd->pool, "SSLStaplingCache: %s", err);
1700 const char *ssl_cmd_SSLUseStapling(cmd_parms *cmd, void *dcfg, int flag)
1702 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1703 sc->server->stapling_enabled = flag ? TRUE : FALSE;
1707 const char *ssl_cmd_SSLStaplingResponseTimeSkew(cmd_parms *cmd, void *dcfg,
1710 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1711 sc->server->stapling_resptime_skew = atoi(arg);
1712 if (sc->server->stapling_resptime_skew < 0) {
1713 return "SSLStaplingResponseTimeSkew: invalid argument";
1718 const char *ssl_cmd_SSLStaplingResponseMaxAge(cmd_parms *cmd, void *dcfg,
1721 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1722 sc->server->stapling_resp_maxage = atoi(arg);
1723 if (sc->server->stapling_resp_maxage < 0) {
1724 return "SSLStaplingResponseMaxAge: invalid argument";
1729 const char *ssl_cmd_SSLStaplingStandardCacheTimeout(cmd_parms *cmd, void *dcfg,
1732 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1733 sc->server->stapling_cache_timeout = atoi(arg);
1734 if (sc->server->stapling_cache_timeout < 0) {
1735 return "SSLStaplingStandardCacheTimeout: invalid argument";
1740 const char *ssl_cmd_SSLStaplingErrorCacheTimeout(cmd_parms *cmd, void *dcfg,
1743 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1744 sc->server->stapling_errcache_timeout = atoi(arg);
1745 if (sc->server->stapling_errcache_timeout < 0) {
1746 return "SSLStaplingErrorCacheTimeout: invalid argument";
1751 const char *ssl_cmd_SSLStaplingReturnResponderErrors(cmd_parms *cmd,
1752 void *dcfg, int flag)
1754 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1755 sc->server->stapling_return_errors = flag ? TRUE : FALSE;
1759 const char *ssl_cmd_SSLStaplingFakeTryLater(cmd_parms *cmd,
1760 void *dcfg, int flag)
1762 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1763 sc->server->stapling_fake_trylater = flag ? TRUE : FALSE;
1767 const char *ssl_cmd_SSLStaplingResponderTimeout(cmd_parms *cmd, void *dcfg,
1770 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1771 sc->server->stapling_responder_timeout = atoi(arg);
1772 sc->server->stapling_responder_timeout *= APR_USEC_PER_SEC;
1773 if (sc->server->stapling_responder_timeout < 0) {
1774 return "SSLStaplingResponderTimeout: invalid argument";
1779 const char *ssl_cmd_SSLStaplingForceURL(cmd_parms *cmd, void *dcfg,
1782 SSLSrvConfigRec *sc = mySrvConfig(cmd->server);
1783 sc->server->stapling_force_url = arg;
1787 #endif /* HAVE_OCSP_STAPLING */
1789 void ssl_hook_ConfigTest(apr_pool_t *pconf, server_rec *s)
1791 apr_file_t *out = NULL;
1792 if (!ap_exists_config_define("DUMP_CERTS")) {
1795 apr_file_open_stdout(&out, pconf);
1796 apr_file_printf(out, "Server certificates:\n");
1798 /* Dump the filenames of all configured server certificates to
1801 SSLSrvConfigRec *sc = mySrvConfig(s);
1803 if (sc && sc->server && sc->server->pks) {
1804 modssl_pk_server_t *const pks = sc->server->pks;
1807 for (i = 0; (i < SSL_AIDX_MAX) && pks->cert_files[i]; i++) {
1808 apr_file_printf(out, " %s\n", pks->cert_files[i]);