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 * Initialization of Servers
29 #include "ssl_private.h"
31 /* _________________________________________________________________
33 ** Module Initialization
34 ** _________________________________________________________________
38 static void ssl_add_version_components(apr_pool_t *p,
41 char *modver = ssl_var_lookup(p, s, NULL, NULL, "SSL_VERSION_INTERFACE");
42 char *libver = ssl_var_lookup(p, s, NULL, NULL, "SSL_VERSION_LIBRARY");
43 char *incver = ssl_var_lookup(p, s, NULL, NULL,
44 "SSL_VERSION_LIBRARY_INTERFACE");
46 ap_add_version_component(p, modver);
47 ap_add_version_component(p, libver);
49 ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
50 "%s compiled against Server: %s, Library: %s",
51 modver, AP_SERVER_BASEVERSION, incver);
56 * Handle the Temporary RSA Keys and DH Params
59 #define MODSSL_TMP_KEY_FREE(mc, type, idx) \
60 if (mc->pTmpKeys[idx]) { \
61 type##_free((type *)mc->pTmpKeys[idx]); \
62 mc->pTmpKeys[idx] = NULL; \
65 #define MODSSL_TMP_KEYS_FREE(mc, type) \
66 MODSSL_TMP_KEY_FREE(mc, type, SSL_TMP_KEY_##type##_512); \
67 MODSSL_TMP_KEY_FREE(mc, type, SSL_TMP_KEY_##type##_1024)
69 static void ssl_tmp_keys_free(server_rec *s)
71 SSLModConfigRec *mc = myModConfig(s);
73 MODSSL_TMP_KEYS_FREE(mc, RSA);
74 MODSSL_TMP_KEYS_FREE(mc, DH);
77 static int ssl_tmp_key_init_rsa(server_rec *s,
80 SSLModConfigRec *mc = myModConfig(s);
82 if (!(mc->pTmpKeys[idx] =
83 RSA_generate_key(bits, RSA_F4, NULL, NULL)))
85 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
86 "Init: Failed to generate temporary "
87 "%d bit RSA private key", bits);
94 static int ssl_tmp_key_init_dh(server_rec *s,
97 SSLModConfigRec *mc = myModConfig(s);
99 if (!(mc->pTmpKeys[idx] =
100 ssl_dh_GetTmpParam(bits)))
102 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
103 "Init: Failed to generate temporary "
104 "%d bit DH parameters", bits);
111 #define MODSSL_TMP_KEY_INIT_RSA(s, bits) \
112 ssl_tmp_key_init_rsa(s, bits, SSL_TMP_KEY_RSA_##bits)
114 #define MODSSL_TMP_KEY_INIT_DH(s, bits) \
115 ssl_tmp_key_init_dh(s, bits, SSL_TMP_KEY_DH_##bits)
117 static int ssl_tmp_keys_init(server_rec *s)
119 ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
120 "Init: Generating temporary RSA private keys (512/1024 bits)");
122 if (MODSSL_TMP_KEY_INIT_RSA(s, 512) ||
123 MODSSL_TMP_KEY_INIT_RSA(s, 1024)) {
127 ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
128 "Init: Generating temporary DH parameters (512/1024 bits)");
130 if (MODSSL_TMP_KEY_INIT_DH(s, 512) ||
131 MODSSL_TMP_KEY_INIT_DH(s, 1024)) {
139 * Per-module initialization
141 int ssl_init_Module(apr_pool_t *p, apr_pool_t *plog,
143 server_rec *base_server)
145 SSLModConfigRec *mc = myModConfig(base_server);
149 /* We initialize mc->pid per-process in the child init,
150 * but it should be initialized for startup before we
151 * call ssl_rand_seed() below.
156 * Let us cleanup on restarts and exists
158 apr_pool_cleanup_register(p, base_server,
160 apr_pool_cleanup_null);
163 * Any init round fixes the global config
165 ssl_config_global_create(base_server); /* just to avoid problems */
166 ssl_config_global_fix(mc);
169 * try to fix the configuration and open the dedicated SSL
170 * logfile as early as possible
172 for (s = base_server; s; s = s->next) {
184 * Create the server host:port string because we need it a lot
186 sc->vhost_id = ssl_util_vhostid(p, s);
187 sc->vhost_id_len = strlen(sc->vhost_id);
189 if (ap_get_server_protocol(s) &&
190 strcmp("https", ap_get_server_protocol(s)) == 0) {
191 sc->enabled = SSL_ENABLED_TRUE;
194 /* If sc->enabled is UNSET, then SSL is optional on this vhost */
195 /* Fix up stuff that may not have been set */
196 if (sc->enabled == SSL_ENABLED_UNSET) {
197 sc->enabled = SSL_ENABLED_FALSE;
199 if (sc->proxy_enabled == UNSET) {
200 sc->proxy_enabled = FALSE;
203 if (sc->session_cache_timeout == UNSET) {
204 sc->session_cache_timeout = SSL_SESSION_CACHE_TIMEOUT;
207 if (sc->server->pphrase_dialog_type == SSL_PPTYPE_UNSET) {
208 sc->server->pphrase_dialog_type = SSL_PPTYPE_BUILTIN;
214 * SSL external crypto device ("engine") support
216 #if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
217 ssl_init_Engine(base_server, p);
221 ssl_util_thread_setup(p);
224 ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
225 "Init: Initialized %s library", SSL_LIBRARY_NAME);
228 * Seed the Pseudo Random Number Generator (PRNG)
229 * only need ptemp here; nothing inside allocated from the pool
230 * needs to live once we return from ssl_rand_seed().
232 ssl_rand_seed(base_server, ptemp, SSL_RSCTX_STARTUP, "Init: ");
235 * read server private keys/public certs into memory.
236 * decrypting any encrypted keys via configured SSLPassPhraseDialogs
237 * anything that needs to live longer than ptemp needs to also survive
238 * restarts, in which case they'll live inside s->process->pool.
240 ssl_pphrase_Handle(base_server, ptemp);
242 if (ssl_tmp_keys_init(base_server)) {
247 * initialize the mutex handling
249 if (!ssl_mutex_init(base_server, p)) {
250 return HTTP_INTERNAL_SERVER_ERROR;
254 * initialize session caching
256 ssl_scache_init(base_server, p);
261 ap_log_error(APLOG_MARK, APLOG_INFO, 0, base_server,
262 "Init: Initializing (virtual) servers for SSL");
264 for (s = base_server; s; s = s->next) {
267 * Either now skip this server when SSL is disabled for
268 * it or give out some information about what we're
273 * Read the server certificate and key
275 ssl_init_ConfigureServer(s, p, ptemp, sc);
279 * Configuration consistency checks
281 ssl_init_CheckServers(base_server, ptemp);
284 * Announce mod_ssl and SSL library in HTTP Server field
285 * as ``mod_ssl/X.X.X OpenSSL/X.X.X''
287 ssl_add_version_components(p, base_server);
289 SSL_init_app_data2_idx(); /* for SSL_get_app_data2() at request time */
295 * Support for external a Crypto Device ("engine"), usually
296 * a hardware accellerator card for crypto operations.
298 #if defined(HAVE_OPENSSL_ENGINE_H) && defined(HAVE_ENGINE_INIT)
299 void ssl_init_Engine(server_rec *s, apr_pool_t *p)
301 SSLModConfigRec *mc = myModConfig(s);
304 if (mc->szCryptoDevice) {
305 if (!(e = ENGINE_by_id(mc->szCryptoDevice))) {
306 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
307 "Init: Failed to load Crypto Device API `%s'",
309 ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
313 if (strEQ(mc->szCryptoDevice, "chil")) {
314 ENGINE_ctrl(e, ENGINE_CTRL_CHIL_SET_FORKCHECK, 1, 0, 0);
317 if (!ENGINE_set_default(e, ENGINE_METHOD_ALL)) {
318 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
319 "Init: Failed to enable Crypto Device API `%s'",
321 ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
330 static void ssl_init_server_check(server_rec *s,
336 * check for important parameters and the
337 * possibility that the user forgot to set them.
339 if (!mctx->pks->cert_files[0] && !mctx->pkcs7) {
340 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
341 "No SSL Certificate set [hint: SSLCertificateFile]");
346 * Check for problematic re-initializations
348 if (mctx->pks->certs[SSL_AIDX_RSA] ||
349 mctx->pks->certs[SSL_AIDX_DSA])
351 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
352 "Illegal attempt to re-initialise SSL for server "
353 "(theoretically shouldn't happen!)");
358 static void ssl_init_ctx_protocol(server_rec *s,
364 SSL_METHOD *method = NULL;
366 int protocol = mctx->protocol;
369 * Create the new per-server SSL context
371 if (protocol == SSL_PROTOCOL_NONE) {
372 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
373 "No SSL protocols available [hint: SSLProtocol]");
378 (protocol & SSL_PROTOCOL_SSLV2 ? "SSLv2, " : ""),
379 (protocol & SSL_PROTOCOL_SSLV3 ? "SSLv3, " : ""),
380 (protocol & SSL_PROTOCOL_TLSV1 ? "TLSv1, " : ""),
382 cp[strlen(cp)-2] = NUL;
384 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
385 "Creating new SSL context (protocols: %s)", cp);
387 if (protocol == SSL_PROTOCOL_SSLV2) {
389 SSLv2_client_method() : /* proxy */
390 SSLv2_server_method(); /* server */
392 else if (protocol == SSL_PROTOCOL_SSLV3) {
394 SSLv3_client_method() : /* proxy */
395 SSLv3_server_method(); /* server */
397 else if (protocol == SSL_PROTOCOL_TLSV1) {
399 TLSv1_client_method() : /* proxy */
400 TLSv1_server_method(); /* server */
402 else { /* For multiple protocols, we need a flexible method */
404 SSLv23_client_method() : /* proxy */
405 SSLv23_server_method(); /* server */
407 ctx = SSL_CTX_new(method);
411 SSL_CTX_set_options(ctx, SSL_OP_ALL);
413 if (!(protocol & SSL_PROTOCOL_SSLV2)) {
414 SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
417 if (!(protocol & SSL_PROTOCOL_SSLV3)) {
418 SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv3);
421 if (!(protocol & SSL_PROTOCOL_TLSV1)) {
422 SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1);
425 #ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
427 SSLSrvConfigRec *sc = mySrvConfig(s);
428 if (sc->cipher_server_pref == TRUE) {
429 SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
434 SSL_CTX_set_app_data(ctx, s);
437 * Configure additional context ingredients
439 SSL_CTX_set_options(ctx, SSL_OP_SINGLE_DH_USE);
441 #ifdef SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION
443 * Disallow a session from being resumed during a renegotiation,
444 * so that an acceptable cipher suite can be negotiated.
446 SSL_CTX_set_options(ctx, SSL_OP_NO_SESSION_RESUMPTION_ON_RENEGOTIATION);
450 static void ssl_init_ctx_session_cache(server_rec *s,
455 SSL_CTX *ctx = mctx->ssl_ctx;
456 SSLModConfigRec *mc = myModConfig(s);
457 long cache_mode = SSL_SESS_CACHE_OFF;
458 if (mc->nSessionCacheMode != SSL_SCMODE_NONE) {
459 /* SSL_SESS_CACHE_NO_INTERNAL will force OpenSSL
460 * to ignore process local-caching and
461 * to always get/set/delete sessions using mod_ssl's callbacks.
463 cache_mode = SSL_SESS_CACHE_SERVER|SSL_SESS_CACHE_NO_INTERNAL;
466 SSL_CTX_set_session_cache_mode(ctx, cache_mode);
468 SSL_CTX_sess_set_new_cb(ctx, ssl_callback_NewSessionCacheEntry);
469 SSL_CTX_sess_set_get_cb(ctx, ssl_callback_GetSessionCacheEntry);
470 SSL_CTX_sess_set_remove_cb(ctx, ssl_callback_DelSessionCacheEntry);
473 static void ssl_init_ctx_callbacks(server_rec *s,
478 SSL_CTX *ctx = mctx->ssl_ctx;
480 SSL_CTX_set_tmp_rsa_callback(ctx, ssl_callback_TmpRSA);
481 SSL_CTX_set_tmp_dh_callback(ctx, ssl_callback_TmpDH);
483 if (s->loglevel >= APLOG_DEBUG) {
484 /* this callback only logs if LogLevel >= info */
485 SSL_CTX_set_info_callback(ctx, ssl_callback_LogTracingState);
489 static void ssl_init_ctx_verify(server_rec *s,
494 SSL_CTX *ctx = mctx->ssl_ctx;
496 int verify = SSL_VERIFY_NONE;
497 STACK_OF(X509_NAME) *ca_list;
499 if (mctx->auth.verify_mode == SSL_CVERIFY_UNSET) {
500 mctx->auth.verify_mode = SSL_CVERIFY_NONE;
503 if (mctx->auth.verify_depth == UNSET) {
504 mctx->auth.verify_depth = 1;
508 * Configure callbacks for SSL context
510 if (mctx->auth.verify_mode == SSL_CVERIFY_REQUIRE) {
511 verify |= SSL_VERIFY_PEER_STRICT;
514 if ((mctx->auth.verify_mode == SSL_CVERIFY_OPTIONAL) ||
515 (mctx->auth.verify_mode == SSL_CVERIFY_OPTIONAL_NO_CA))
517 verify |= SSL_VERIFY_PEER;
520 SSL_CTX_set_verify(ctx, verify, ssl_callback_SSLVerify);
523 * Configure Client Authentication details
525 if (mctx->auth.ca_cert_file || mctx->auth.ca_cert_path) {
526 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
527 "Configuring client authentication");
529 if (!SSL_CTX_load_verify_locations(ctx,
530 MODSSL_PCHAR_CAST mctx->auth.ca_cert_file,
531 MODSSL_PCHAR_CAST mctx->auth.ca_cert_path))
533 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
534 "Unable to configure verify locations "
535 "for client authentication");
536 ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
540 if (mctx->pks && (mctx->pks->ca_name_file || mctx->pks->ca_name_path)) {
541 ca_list = ssl_init_FindCAList(s, ptemp,
542 mctx->pks->ca_name_file,
543 mctx->pks->ca_name_path);
545 ca_list = ssl_init_FindCAList(s, ptemp,
546 mctx->auth.ca_cert_file,
547 mctx->auth.ca_cert_path);
549 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
550 "Unable to determine list of acceptable "
551 "CA certificates for client authentication");
555 SSL_CTX_set_client_CA_list(ctx, (STACK *)ca_list);
559 * Give a warning when no CAs were configured but client authentication
560 * should take place. This cannot work.
562 if (mctx->auth.verify_mode == SSL_CVERIFY_REQUIRE) {
563 ca_list = (STACK_OF(X509_NAME) *)SSL_CTX_get_client_CA_list(ctx);
565 if (sk_X509_NAME_num(ca_list) == 0) {
566 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
567 "Init: Oops, you want to request client "
568 "authentication, but no CAs are known for "
569 "verification!? [Hint: SSLCACertificate*]");
574 static void ssl_init_ctx_cipher_suite(server_rec *s,
579 SSL_CTX *ctx = mctx->ssl_ctx;
580 const char *suite = mctx->auth.cipher_suite;
583 * Configure SSL Cipher Suite
589 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
590 "Configuring permitted SSL ciphers [%s]",
593 if (!SSL_CTX_set_cipher_list(ctx, MODSSL_PCHAR_CAST suite)) {
594 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
595 "Unable to configure permitted SSL ciphers");
596 ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
601 static void ssl_init_ctx_crl(server_rec *s,
607 * Configure Certificate Revocation List (CRL) Details
610 if (!(mctx->crl_file || mctx->crl_path)) {
614 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
615 "Configuring certificate revocation facility");
618 SSL_X509_STORE_create((char *)mctx->crl_file,
619 (char *)mctx->crl_path);
622 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
623 "Unable to configure X.509 CRL storage "
624 "for certificate revocation");
625 ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
630 static void ssl_init_ctx_pkcs7_cert_chain(server_rec *s, modssl_ctx_t *mctx)
632 STACK_OF(X509) *certs = ssl_read_pkcs7(s, mctx->pkcs7);
635 if (!mctx->ssl_ctx->extra_certs)
636 for (n = 1; n < sk_X509_num(certs); ++n)
637 SSL_CTX_add_extra_chain_cert(mctx->ssl_ctx, sk_X509_value(certs, n));
640 static void ssl_init_ctx_cert_chain(server_rec *s,
645 BOOL skip_first = FALSE;
647 const char *chain = mctx->cert_chain;
650 ssl_init_ctx_pkcs7_cert_chain(s, mctx);
655 * Optionally configure extra server certificate chain certificates.
656 * This is usually done by OpenSSL automatically when one of the
657 * server cert issuers are found under SSLCACertificatePath or in
658 * SSLCACertificateFile. But because these are intended for client
659 * authentication it can conflict. For instance when you use a
660 * Global ID server certificate you've to send out the intermediate
661 * CA certificate, too. When you would just configure this with
662 * SSLCACertificateFile and also use client authentication mod_ssl
663 * would accept all clients also issued by this CA. Obviously this
664 * isn't what we want in this situation. So this feature here exists
665 * to allow one to explicity configure CA certificates which are
666 * used only for the server certificate chain.
672 for (i = 0; (i < SSL_AIDX_MAX) && mctx->pks->cert_files[i]; i++) {
673 if (strEQ(mctx->pks->cert_files[i], chain)) {
679 n = SSL_CTX_use_certificate_chain(mctx->ssl_ctx,
683 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
684 "Failed to configure CA certificate chain!");
688 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
689 "Configuring server certificate chain "
690 "(%d CA certificate%s)",
691 n, n == 1 ? "" : "s");
694 static void ssl_init_ctx(server_rec *s,
699 ssl_init_ctx_protocol(s, p, ptemp, mctx);
701 ssl_init_ctx_session_cache(s, p, ptemp, mctx);
703 ssl_init_ctx_callbacks(s, p, ptemp, mctx);
705 ssl_init_ctx_verify(s, p, ptemp, mctx);
707 ssl_init_ctx_cipher_suite(s, p, ptemp, mctx);
709 ssl_init_ctx_crl(s, p, ptemp, mctx);
712 /* XXX: proxy support? */
713 ssl_init_ctx_cert_chain(s, p, ptemp, mctx);
717 static int ssl_server_import_cert(server_rec *s,
722 SSLModConfigRec *mc = myModConfig(s);
724 MODSSL_D2I_X509_CONST unsigned char *ptr;
725 const char *type = ssl_asn1_keystr(idx);
728 if (!(asn1 = ssl_asn1_table_get(mc->tPublicCert, id))) {
732 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
733 "Configuring %s server certificate", type);
736 if (!(cert = d2i_X509(NULL, &ptr, asn1->nData))) {
737 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
738 "Unable to import %s server certificate", type);
739 ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
743 if (SSL_CTX_use_certificate(mctx->ssl_ctx, cert) <= 0) {
744 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
745 "Unable to configure %s server certificate", type);
746 ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
750 mctx->pks->certs[idx] = cert;
755 static int ssl_server_import_key(server_rec *s,
760 SSLModConfigRec *mc = myModConfig(s);
762 MODSSL_D2I_PrivateKey_CONST unsigned char *ptr;
763 const char *type = ssl_asn1_keystr(idx);
764 int pkey_type = (idx == SSL_AIDX_RSA) ? EVP_PKEY_RSA : EVP_PKEY_DSA;
767 if (!(asn1 = ssl_asn1_table_get(mc->tPrivateKey, id))) {
771 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
772 "Configuring %s server private key", type);
775 if (!(pkey = d2i_PrivateKey(pkey_type, NULL, &ptr, asn1->nData)))
777 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
778 "Unable to import %s server private key", type);
779 ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
783 if (SSL_CTX_use_PrivateKey(mctx->ssl_ctx, pkey) <= 0) {
784 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
785 "Unable to configure %s server private key", type);
786 ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
791 * XXX: wonder if this is still needed, this is old todo doc.
792 * (see http://www.psy.uq.edu.au/~ftp/Crypto/ssleay/TODO.html)
794 if ((pkey_type == EVP_PKEY_DSA) && mctx->pks->certs[idx]) {
795 EVP_PKEY *pubkey = X509_get_pubkey(mctx->pks->certs[idx]);
797 if (pubkey && EVP_PKEY_missing_parameters(pubkey)) {
798 EVP_PKEY_copy_parameters(pubkey, pkey);
799 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
800 "Copying DSA parameters from private key to certificate");
801 ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, s);
802 EVP_PKEY_free(pubkey);
806 mctx->pks->keys[idx] = pkey;
811 static void ssl_check_public_cert(server_rec *s,
824 * Some information about the certificate(s)
827 if (SSL_X509_isSGC(cert)) {
828 ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
829 "%s server certificate enables "
830 "Server Gated Cryptography (SGC)",
831 ssl_asn1_keystr(type));
834 if (SSL_X509_getBC(cert, &is_ca, &pathlen)) {
836 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
837 "%s server certificate is a CA certificate "
838 "(BasicConstraints: CA == TRUE !?)",
839 ssl_asn1_keystr(type));
843 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
844 "%s server certificate is not a leaf certificate "
845 "(BasicConstraints: pathlen == %d > 0 !?)",
846 ssl_asn1_keystr(type), pathlen);
850 if (SSL_X509_getCN(ptemp, cert, &cn)) {
851 int fnm_flags = APR_FNM_PERIOD|APR_FNM_CASE_BLIND;
853 if (apr_fnmatch_test(cn)) {
854 if (apr_fnmatch(cn, s->server_hostname,
855 fnm_flags) == APR_FNM_NOMATCH) {
856 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
857 "%s server certificate wildcard CommonName "
858 "(CN) `%s' does NOT match server name!?",
859 ssl_asn1_keystr(type), cn);
862 else if (strNE(s->server_hostname, cn)) {
863 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
864 "%s server certificate CommonName (CN) `%s' "
865 "does NOT match server name!?",
866 ssl_asn1_keystr(type), cn);
871 static void ssl_init_server_certs(server_rec *s,
876 const char *rsa_id, *dsa_id;
877 const char *vhost_id = mctx->sc->vhost_id;
879 int have_rsa, have_dsa;
881 rsa_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_RSA);
882 dsa_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_DSA);
884 have_rsa = ssl_server_import_cert(s, mctx, rsa_id, SSL_AIDX_RSA);
885 have_dsa = ssl_server_import_cert(s, mctx, dsa_id, SSL_AIDX_DSA);
887 if (!(have_rsa || have_dsa)) {
888 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
889 "Oops, no RSA or DSA server certificate found "
890 "for '%s:%d'?!", s->server_hostname, s->port);
894 for (i = 0; i < SSL_AIDX_MAX; i++) {
895 ssl_check_public_cert(s, ptemp, mctx->pks->certs[i], i);
898 have_rsa = ssl_server_import_key(s, mctx, rsa_id, SSL_AIDX_RSA);
899 have_dsa = ssl_server_import_key(s, mctx, dsa_id, SSL_AIDX_DSA);
901 if (!(have_rsa || have_dsa)) {
902 ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
903 "Oops, no RSA or DSA server private key found?!");
908 static void ssl_init_proxy_certs(server_rec *s,
914 STACK_OF(X509_INFO) *sk;
915 modssl_pk_proxy_t *pkp = mctx->pkp;
917 SSL_CTX_set_client_cert_cb(mctx->ssl_ctx,
918 ssl_callback_proxy_cert);
920 if (!(pkp->cert_file || pkp->cert_path)) {
924 sk = sk_X509_INFO_new_null();
926 if (pkp->cert_file) {
927 SSL_X509_INFO_load_file(ptemp, sk, pkp->cert_file);
930 if (pkp->cert_path) {
931 SSL_X509_INFO_load_path(ptemp, sk, pkp->cert_path);
934 if ((ncerts = sk_X509_INFO_num(sk)) <= 0) {
935 sk_X509_INFO_free(sk);
936 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
937 "no client certs found for SSL proxy");
941 /* Check that all client certs have got certificates and private
943 for (n = 0; n < ncerts; n++) {
944 X509_INFO *inf = sk_X509_INFO_value(sk, n);
946 if (!inf->x509 || !inf->x_pkey) {
947 sk_X509_INFO_free(sk);
948 ap_log_error(APLOG_MARK, APLOG_STARTUP, 0, s,
949 "incomplete client cert configured for SSL proxy "
950 "(missing or encrypted private key?)");
956 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
957 "loaded %d client certs for SSL proxy",
962 static void ssl_init_proxy_ctx(server_rec *s,
967 ssl_init_ctx(s, p, ptemp, sc->proxy);
969 ssl_init_proxy_certs(s, p, ptemp, sc->proxy);
972 static void ssl_init_server_ctx(server_rec *s,
977 ssl_init_server_check(s, p, ptemp, sc->server);
979 ssl_init_ctx(s, p, ptemp, sc->server);
981 ssl_init_server_certs(s, p, ptemp, sc->server);
985 * Configure a particular server
987 void ssl_init_ConfigureServer(server_rec *s,
992 /* Initialize the server if SSL is enabled or optional.
994 if ((sc->enabled == SSL_ENABLED_TRUE) || (sc->enabled == SSL_ENABLED_OPTIONAL)) {
995 ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
996 "Configuring server for SSL protocol");
997 ssl_init_server_ctx(s, p, ptemp, sc);
1000 if (sc->proxy_enabled) {
1001 ssl_init_proxy_ctx(s, p, ptemp, sc);
1005 void ssl_init_CheckServers(server_rec *base_server, apr_pool_t *p)
1008 SSLSrvConfigRec *sc;
1013 BOOL conflict = FALSE;
1016 * Give out warnings when a server has HTTPS configured
1017 * for the HTTP port or vice versa
1019 for (s = base_server; s; s = s->next) {
1020 sc = mySrvConfig(s);
1022 if ((sc->enabled == SSL_ENABLED_TRUE) && (s->port == DEFAULT_HTTP_PORT)) {
1023 ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
1025 "Init: (%s) You configured HTTPS(%d) "
1026 "on the standard HTTP(%d) port!",
1027 ssl_util_vhostid(p, s),
1028 DEFAULT_HTTPS_PORT, DEFAULT_HTTP_PORT);
1031 if ((sc->enabled == SSL_ENABLED_FALSE) && (s->port == DEFAULT_HTTPS_PORT)) {
1032 ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
1034 "Init: (%s) You configured HTTP(%d) "
1035 "on the standard HTTPS(%d) port!",
1036 ssl_util_vhostid(p, s),
1037 DEFAULT_HTTP_PORT, DEFAULT_HTTPS_PORT);
1042 * Give out warnings when more than one SSL-aware virtual server uses the
1043 * same IP:port. This doesn't work because mod_ssl then will always use
1044 * just the certificate/keys of one virtual host (which one cannot be said
1045 * easily - but that doesn't matter here).
1047 table = apr_hash_make(p);
1049 for (s = base_server; s; s = s->next) {
1052 sc = mySrvConfig(s);
1054 if (!((sc->enabled == SSL_ENABLED_TRUE) && s->addrs)) {
1058 apr_sockaddr_ip_get(&addr, s->addrs->host_addr);
1059 key = apr_psprintf(p, "%s:%u", addr, s->addrs->host_port);
1062 if ((ps = (server_rec *)apr_hash_get(table, key, klen))) {
1063 ap_log_error(APLOG_MARK, APLOG_WARNING, 0,
1065 "Init: SSL server IP/port conflict: "
1066 "%s (%s:%d) vs. %s (%s:%d)",
1067 ssl_util_vhostid(p, s),
1068 (s->defn_name ? s->defn_name : "unknown"),
1069 s->defn_line_number,
1070 ssl_util_vhostid(p, ps),
1071 (ps->defn_name ? ps->defn_name : "unknown"),
1072 ps->defn_line_number);
1077 apr_hash_set(table, key, klen, s);
1081 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, base_server,
1082 "Init: You should not use name-based "
1083 "virtual hosts in conjunction with SSL!!");
1087 #ifdef SSLC_VERSION_NUMBER
1088 static int ssl_init_FindCAList_X509NameCmp(char **a, char **b)
1090 return(X509_NAME_cmp((void*)*a, (void*)*b));
1093 static int ssl_init_FindCAList_X509NameCmp(X509_NAME **a, X509_NAME **b)
1095 return(X509_NAME_cmp(*a, *b));
1099 static void ssl_init_PushCAList(STACK_OF(X509_NAME) *ca_list,
1100 server_rec *s, const char *file)
1103 STACK_OF(X509_NAME) *sk;
1105 sk = (STACK_OF(X509_NAME) *)
1106 SSL_load_client_CA_file(MODSSL_PCHAR_CAST file);
1112 for (n = 0; n < sk_X509_NAME_num(sk); n++) {
1114 X509_NAME *name = sk_X509_NAME_value(sk, n);
1116 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s,
1117 "CA certificate: %s",
1118 X509_NAME_oneline(name, name_buf, sizeof(name_buf)));
1121 * note that SSL_load_client_CA_file() checks for duplicates,
1122 * but since we call it multiple times when reading a directory
1123 * we must also check for duplicates ourselves.
1126 if (sk_X509_NAME_find(ca_list, name) < 0) {
1127 /* this will be freed when ca_list is */
1128 sk_X509_NAME_push(ca_list, name);
1131 /* need to free this ourselves, else it will leak */
1132 X509_NAME_free(name);
1136 sk_X509_NAME_free(sk);
1139 STACK_OF(X509_NAME) *ssl_init_FindCAList(server_rec *s,
1141 const char *ca_file,
1142 const char *ca_path)
1144 STACK_OF(X509_NAME) *ca_list;
1147 * Start with a empty stack/list where new
1148 * entries get added in sorted order.
1150 ca_list = sk_X509_NAME_new(ssl_init_FindCAList_X509NameCmp);
1153 * Process CA certificate bundle file
1156 ssl_init_PushCAList(ca_list, s, ca_file);
1160 * Process CA certificate path files
1164 apr_finfo_t direntry;
1165 apr_int32_t finfo_flags = APR_FINFO_TYPE|APR_FINFO_NAME;
1168 if ((rv = apr_dir_open(&dir, ca_path, ptemp)) != APR_SUCCESS) {
1169 ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
1170 "Failed to open Certificate Path `%s'",
1175 while ((apr_dir_read(&direntry, finfo_flags, dir)) == APR_SUCCESS) {
1177 if (direntry.filetype == APR_DIR) {
1178 continue; /* don't try to load directories */
1180 file = apr_pstrcat(ptemp, ca_path, "/", direntry.name, NULL);
1181 ssl_init_PushCAList(ca_list, s, file);
1190 sk_X509_NAME_set_cmp_func(ca_list, NULL);
1195 void ssl_init_Child(apr_pool_t *p, server_rec *s)
1197 SSLModConfigRec *mc = myModConfig(s);
1198 mc->pid = getpid(); /* only call getpid() once per-process */
1200 /* XXX: there should be an ap_srand() function */
1201 srand((unsigned int)time(NULL));
1203 /* open the mutex lockfile */
1204 ssl_mutex_reinit(s, p);
1207 #define MODSSL_CFG_ITEM_FREE(func, item) \
1213 static void ssl_init_ctx_cleanup(modssl_ctx_t *mctx)
1215 MODSSL_CFG_ITEM_FREE(X509_STORE_free, mctx->crl);
1217 MODSSL_CFG_ITEM_FREE(SSL_CTX_free, mctx->ssl_ctx);
1220 static void ssl_init_ctx_cleanup_proxy(modssl_ctx_t *mctx)
1222 ssl_init_ctx_cleanup(mctx);
1224 if (mctx->pkp->certs) {
1225 sk_X509_INFO_pop_free(mctx->pkp->certs, X509_INFO_free);
1226 mctx->pkp->certs = NULL;
1230 static void ssl_init_ctx_cleanup_server(modssl_ctx_t *mctx)
1234 ssl_init_ctx_cleanup(mctx);
1236 for (i=0; i < SSL_AIDX_MAX; i++) {
1237 MODSSL_CFG_ITEM_FREE(X509_free,
1238 mctx->pks->certs[i]);
1240 MODSSL_CFG_ITEM_FREE(EVP_PKEY_free,
1241 mctx->pks->keys[i]);
1245 apr_status_t ssl_init_ModuleKill(void *data)
1247 SSLSrvConfigRec *sc;
1248 server_rec *base_server = (server_rec *)data;
1252 * Drop the session cache and mutex
1254 ssl_scache_kill(base_server);
1257 * Destroy the temporary keys and params
1259 ssl_tmp_keys_free(base_server);
1262 * Free the non-pool allocated structures
1263 * in the per-server configurations
1265 for (s = base_server; s; s = s->next) {
1266 sc = mySrvConfig(s);
1268 ssl_init_ctx_cleanup_proxy(sc->proxy);
1270 ssl_init_ctx_cleanup_server(sc->server);