ssl_engine_kernel.c revision 40beb03c240a9c60805388592f1005d9bf9d2362
02c335c23bf5fa225a467c19f2c063fb0dc7b8c3Timo Sirainen/* Licensed to the Apache Software Foundation (ASF) under one or more
9fb018dea4e2073639249ea8a14ae27cab2c0aacTimo Sirainen * contributor license agreements. See the NOTICE file distributed with
9fb018dea4e2073639249ea8a14ae27cab2c0aacTimo Sirainen * this work for additional information regarding copyright ownership.
9ca6d68fbad1892423ca798818f579c95475a19aTimo Sirainen * The ASF licenses this file to You under the Apache License, Version 2.0
e65df911d966a0b4623e287d4669253cc46bbe0fTimo Sirainen * (the "License"); you may not use this file except in compliance with
e65df911d966a0b4623e287d4669253cc46bbe0fTimo Sirainen * the License. You may obtain a copy of the License at
94a77d6e5d7600859e4c5e4a7ea19dc3e91998b9Timo Sirainen * Unless required by applicable law or agreed to in writing, software
9ca6d68fbad1892423ca798818f579c95475a19aTimo Sirainen * distributed under the License is distributed on an "AS IS" BASIS,
9fb018dea4e2073639249ea8a14ae27cab2c0aacTimo Sirainen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9fb018dea4e2073639249ea8a14ae27cab2c0aacTimo Sirainen * See the License for the specific language governing permissions and
eda647108a7dab36a4133bbee1916720b4b1c97eTimo Sirainen * limitations under the License.
94a77d6e5d7600859e4c5e4a7ea19dc3e91998b9Timo Sirainen * _ __ ___ ___ __| | ___ ___| | mod_ssl
94a77d6e5d7600859e4c5e4a7ea19dc3e91998b9Timo Sirainen * | '_ ` _ \ / _ \ / _` | / __/ __| | Apache Interface to OpenSSL
9ca6d68fbad1892423ca798818f579c95475a19aTimo Sirainen * | | | | | | (_) | (_| | \__ \__ \ |
94a77d6e5d7600859e4c5e4a7ea19dc3e91998b9Timo Sirainen * |_| |_| |_|\___/ \__,_|___|___/___/_|
94a77d6e5d7600859e4c5e4a7ea19dc3e91998b9Timo Sirainen * The SSL engine kernel
94a77d6e5d7600859e4c5e4a7ea19dc3e91998b9Timo Sirainen /* ``It took me fifteen years to discover
b1a2d2042e8c7e99983175eb462b82cc7a8cb70bTimo Sirainen I had no talent for programming, but
94a77d6e5d7600859e4c5e4a7ea19dc3e91998b9Timo Sirainen I couldn't give it up because by that
94a77d6e5d7600859e4c5e4a7ea19dc3e91998b9Timo Sirainen time I was too famous.''
94a77d6e5d7600859e4c5e4a7ea19dc3e91998b9Timo Sirainen -- Unknown */
854574e0a4a4d38b0ada296cc85eed3530436c69Timo Sirainenstatic void ssl_configure_env(request_rec *r, SSLConnRec *sslconn);
854574e0a4a4d38b0ada296cc85eed3530436c69Timo Sirainen#define SWITCH_STATUS_LINE "HTTP/1.1 101 Switching Protocols"
854574e0a4a4d38b0ada296cc85eed3530436c69Timo Sirainen#define UPGRADE_HEADER "Upgrade: TLS/1.0, HTTP/1.1"
854574e0a4a4d38b0ada296cc85eed3530436c69Timo Sirainen#define CONNECTION_HEADER "Connection: Upgrade"
f4fdc28d5df5eee00528a37e198493829e7df0abTimo Sirainen/* Perform an upgrade-to-TLS for the given request, per RFC 2817. */
f4fdc28d5df5eee00528a37e198493829e7df0abTimo Sirainenstatic apr_status_t upgrade_connection(request_rec *r)
854574e0a4a4d38b0ada296cc85eed3530436c69Timo Sirainen "upgrading connection to TLS");
854574e0a4a4d38b0ada296cc85eed3530436c69Timo Sirainen bb = apr_brigade_create(r->pool, conn->bucket_alloc);
e39459afd08b437e72fd72cd60ff409230695bceTimo Sirainen rv = ap_fputstrs(conn->output_filters, bb, SWITCH_STATUS_LINE, CRLF,
e39459afd08b437e72fd72cd60ff409230695bceTimo Sirainen UPGRADE_HEADER, CRLF, CONNECTION_HEADER, CRLF, CRLF, NULL);
e39459afd08b437e72fd72cd60ff409230695bceTimo Sirainen rv = ap_pass_brigade(conn->output_filters, bb);
d5e131e809cf52342d904857d41c2bb41973dde8Timo Sirainen "failed to send 101 interim response for connection "
2ddc5efd47452644be369fa86e978cc05a508217Timo Sirainen /* Perform initial SSL handshake. */
2ddc5efd47452644be369fa86e978cc05a508217Timo Sirainen "TLS upgrade handshake failed: not accepted by client!?");
2ddc5efd47452644be369fa86e978cc05a508217Timo Sirainen * Post Read Request Handler
9fb018dea4e2073639249ea8a14ae27cab2c0aacTimo Sirainen /* Perform TLS upgrade here if "SSLEngine optional" is configured,
e2170d0dfac94f795ab5dbe05939393c14b1946cTimo Sirainen * SSL is not already set up for this connection, and the client
e2170d0dfac94f795ab5dbe05939393c14b1946cTimo Sirainen * has sent a suitable Upgrade header. */
e2170d0dfac94f795ab5dbe05939393c14b1946cTimo Sirainen if (sc->enabled == SSL_ENABLED_OPTIONAL && !myConnConfig(r->connection)
94a77d6e5d7600859e4c5e4a7ea19dc3e91998b9Timo Sirainen && (upgrade = apr_table_get(r->headers_in, "Upgrade")) != NULL
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen && ap_find_token(r->pool, upgrade, "TLS/1.0")) {
9fb018dea4e2073639249ea8a14ae27cab2c0aacTimo Sirainen thisport = apr_psprintf(r->pool, ":%u", port);
9fb018dea4e2073639249ea8a14ae27cab2c0aacTimo Sirainen "Reason: You're speaking plain HTTP "
9fb018dea4e2073639249ea8a14ae27cab2c0aacTimo Sirainen "to an SSL-enabled server port.<br />\n"
adcb46fe2c6d1139dfbd8ab08a8fbe96e53f8fd6Timo Sirainen "Instead use the HTTPS scheme to access "
9fb018dea4e2073639249ea8a14ae27cab2c0aacTimo Sirainen "this URL, please.<br />\n"
9fb018dea4e2073639249ea8a14ae27cab2c0aacTimo Sirainen "<blockquote>Hint: "
5940a2b112cdabc534df17179e63208f4c81a28bTimo Sirainen "<a href=\"%s\"><b>%s</b></a></blockquote>",
9fb018dea4e2073639249ea8a14ae27cab2c0aacTimo Sirainen apr_table_setn(r->notes, "error-notes", errmsg);
adcb46fe2c6d1139dfbd8ab08a8fbe96e53f8fd6Timo Sirainen /* Now that we have caught this error, forget it. we are done
50ffc12831eff618d35a8ee7537b61eaa95a4adeTimo Sirainen * with using SSL on this request.
13aff14ae8b2fb88c39bacc132b468ae82d63145Timo Sirainen * Get the SSL connection structure and perform the
adcb46fe2c6d1139dfbd8ab08a8fbe96e53f8fd6Timo Sirainen * delayed interlinking from SSL back to request_rec
adcb46fe2c6d1139dfbd8ab08a8fbe96e53f8fd6Timo Sirainen * Log information about incoming HTTPS requests
adcb46fe2c6d1139dfbd8ab08a8fbe96e53f8fd6Timo Sirainen if (r->server->loglevel >= APLOG_INFO && ap_is_initial_req(r)) {
adcb46fe2c6d1139dfbd8ab08a8fbe96e53f8fd6Timo Sirainen ap_log_error(APLOG_MARK, APLOG_INFO, 0, r->server,
adcb46fe2c6d1139dfbd8ab08a8fbe96e53f8fd6Timo Sirainen "%s HTTPS request received for child %ld (server %s)",
adcb46fe2c6d1139dfbd8ab08a8fbe96e53f8fd6Timo Sirainen "Initial (No.1)" :
adcb46fe2c6d1139dfbd8ab08a8fbe96e53f8fd6Timo Sirainen /* SetEnvIf ssl-*-shutdown flags can only be per-server,
adcb46fe2c6d1139dfbd8ab08a8fbe96e53f8fd6Timo Sirainen * so they won't change across keepalive requests
9fb018dea4e2073639249ea8a14ae27cab2c0aacTimo Sirainen if (sslconn->shutdown_type == SSL_SHUTDOWN_TYPE_UNSET) {
50ffc12831eff618d35a8ee7537b61eaa95a4adeTimo Sirainen * Move SetEnvIf information from request_rec to conn_rec/BUFF
50ffc12831eff618d35a8ee7537b61eaa95a4adeTimo Sirainen * to allow the close connection handler to use them.
50ffc12831eff618d35a8ee7537b61eaa95a4adeTimo Sirainenstatic void ssl_configure_env(request_rec *r, SSLConnRec *sslconn)
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen const apr_array_header_t *arr = apr_table_elts(r->subprocess_env);
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen const apr_table_entry_t *elts = (const apr_table_entry_t *)arr->elts;
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen sslconn->shutdown_type = SSL_SHUTDOWN_TYPE_STANDARD;
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen /* being case-sensitive here.
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen * and not checking for the -shutdown since these are the only
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen * SetEnvIf "flags" we support
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen sslconn->shutdown_type = SSL_SHUTDOWN_TYPE_UNCLEAN;
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen sslconn->shutdown_type = SSL_SHUTDOWN_TYPE_ACCURATE;
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen return; /* should only ever be one ssl-*-shutdown */
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen * Access Handler
214fc90c61133ea4a3521dd7313fe488a55ac0c6Timo Sirainen SSLConnRec *sslconn = myConnConfig(r->connection);
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen BOOL renegotiate = FALSE, renegotiate_quick = FALSE;
214fc90c61133ea4a3521dd7313fe488a55ac0c6Timo Sirainen STACK_OF(SSL_CIPHER) *cipher_list_old = NULL, *cipher_list = NULL;
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen * Support for SSLRequireSSL directive
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen /* This vhost was configured for optional SSL, just tell the
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen * client that we need to upgrade.
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen apr_table_setn(r->err_headers_out, "Upgrade", "TLS/1.0, HTTP/1.1");
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen apr_table_setn(r->err_headers_out, "Connection", "Upgrade");
6df0ab0c1ab91f06b6418cb30eff44405a1b8f02Timo Sirainen "access to %s failed, reason: %s",
6df0ab0c1ab91f06b6418cb30eff44405a1b8f02Timo Sirainen /* remember forbidden access for strict require option */
6df0ab0c1ab91f06b6418cb30eff44405a1b8f02Timo Sirainen apr_table_setn(r->notes, "ssl-access-forbidden", "1");
15979d11259a2391c943bb47af4d174df52d9eb9Timo Sirainen * Check to see whether SSL is in use; if it's not, then no
6df0ab0c1ab91f06b6418cb30eff44405a1b8f02Timo Sirainen * further access control checks are relevant. (the test for
6df0ab0c1ab91f06b6418cb30eff44405a1b8f02Timo Sirainen * sc->enabled is probably strictly unnecessary)
6df0ab0c1ab91f06b6418cb30eff44405a1b8f02Timo Sirainen if (sc->enabled == SSL_ENABLED_FALSE || !ssl) {
6df0ab0c1ab91f06b6418cb30eff44405a1b8f02Timo Sirainen * Support for per-directory reconfigured SSL connection parameters.
94a77d6e5d7600859e4c5e4a7ea19dc3e91998b9Timo Sirainen * This is implemented by forcing an SSL renegotiation with the
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen * reconfigured parameter suite. But Apache's internal API processing
94a77d6e5d7600859e4c5e4a7ea19dc3e91998b9Timo Sirainen * makes our life very hard here, because when internal sub-requests occur
94a77d6e5d7600859e4c5e4a7ea19dc3e91998b9Timo Sirainen * we nevertheless should avoid multiple unnecessary SSL handshakes (they
94a77d6e5d7600859e4c5e4a7ea19dc3e91998b9Timo Sirainen * require extra network I/O and especially time to perform).
2ddc5efd47452644be369fa86e978cc05a508217Timo Sirainen * But the optimization for filtering out the unnecessary handshakes isn't
2ddc5efd47452644be369fa86e978cc05a508217Timo Sirainen * obvious and trivial. Especially because while Apache is in its
2ddc5efd47452644be369fa86e978cc05a508217Timo Sirainen * sub-request processing the client could force additional handshakes,
2ddc5efd47452644be369fa86e978cc05a508217Timo Sirainen * too. And these take place perhaps without our notice. So the only
2ddc5efd47452644be369fa86e978cc05a508217Timo Sirainen * possibility is to explicitly _ask_ OpenSSL whether the renegotiation
2ddc5efd47452644be369fa86e978cc05a508217Timo Sirainen * has to be performed or not. It has to performed when some parameters
2ddc5efd47452644be369fa86e978cc05a508217Timo Sirainen * which were previously known (by us) are not those we've now
94a77d6e5d7600859e4c5e4a7ea19dc3e91998b9Timo Sirainen * reconfigured (as known by OpenSSL) or (in optimized way) at least when
94a77d6e5d7600859e4c5e4a7ea19dc3e91998b9Timo Sirainen * the reconfigured parameter suite is stronger (more restrictions) than
9fb018dea4e2073639249ea8a14ae27cab2c0aacTimo Sirainen * the currently active one.
5085686ff2b4be28e7d631e1bbfa32afe427b7c7Timo Sirainen * We will switch to another virtualhost and to its ssl_ctx
5085686ff2b4be28e7d631e1bbfa32afe427b7c7Timo Sirainen * if changed, we will force a renegotiation.
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen if (r->hostname && !SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name)) {
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen if (ssl_set_vhost_ctx(ssl,(char *)r->hostname) &&
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen * Override of SSLCipherSuite
ffb886eb9c3682bb891206cced9623368035d739Timo Sirainen * We provide two options here:
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen * o The paranoid and default approach where we force a renegotiation when
adcb46fe2c6d1139dfbd8ab08a8fbe96e53f8fd6Timo Sirainen * the cipher suite changed in _any_ way (which is straight-forward but
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen * often forces renegotiations too often and is perhaps not what the
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen * user actually wanted).
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen * o The optimized and still secure way where we force a renegotiation
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen * only if the currently active cipher is no longer contained in the
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen * reconfigured/new cipher suite. Any other changes are not important
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen * because it's the servers choice to select a cipher from the ones the
bf611d43256ef8ee3e1c1ce8e1257920f2075278Timo Sirainen * client supports. So as long as the current cipher is still in the new
bf611d43256ef8ee3e1c1ce8e1257920f2075278Timo Sirainen * cipher suite we're happy. Because we can assume we would have
bf611d43256ef8ee3e1c1ce8e1257920f2075278Timo Sirainen * selected it again even when other (better) ciphers exists now in the
bf611d43256ef8ee3e1c1ce8e1257920f2075278Timo Sirainen * new cipher suite. This approach is fine because the user explicitly
bf611d43256ef8ee3e1c1ce8e1257920f2075278Timo Sirainen * has to enable this via ``SSLOptions +OptRenegotiate''. So we do no
bf611d43256ef8ee3e1c1ce8e1257920f2075278Timo Sirainen * implicit optimizations.
adcb46fe2c6d1139dfbd8ab08a8fbe96e53f8fd6Timo Sirainen /* remember old state */
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen cipher_list_old = (STACK_OF(SSL_CIPHER) *)SSL_get_ciphers(ssl);
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen cipher_list_old = sk_SSL_CIPHER_dup(cipher_list_old);
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen /* configure new state */
d81b80bac97040d5e737f23ce1ee2eb4d7cc16cfTimo Sirainen if (!modssl_set_cipher_list(ssl, dc->szCipherSuite)) {
d81b80bac97040d5e737f23ce1ee2eb4d7cc16cfTimo Sirainen ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen "Unable to reconfigure (per-directory) "
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen "permitted SSL ciphers");
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, r->server);
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen /* determine whether a renegotiation has to be forced */
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen cipher_list = (STACK_OF(SSL_CIPHER) *)SSL_get_ciphers(ssl);
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen /* optimized way */
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen (sk_SSL_CIPHER_find(cipher_list, cipher) < 0))
ecd69c4e8371853667e01b0c16d436ef7f7393e2Timo Sirainen /* paranoid way */
0daf6ffdc0958f3dff3a81201e7cdbb1ecf0d28bTimo Sirainen !renegotiate && (n < sk_SSL_CIPHER_num(cipher_list));
0daf6ffdc0958f3dff3a81201e7cdbb1ecf0d28bTimo Sirainen SSL_CIPHER *value = sk_SSL_CIPHER_value(cipher_list, n);
fda7b3649d2ccdb4a95f5bf09eb8cf5435d57261Timo Sirainen if (sk_SSL_CIPHER_find(cipher_list_old, value) < 0) {
15979d11259a2391c943bb47af4d174df52d9eb9Timo Sirainen !renegotiate && (n < sk_SSL_CIPHER_num(cipher_list_old));
0daf6ffdc0958f3dff3a81201e7cdbb1ecf0d28bTimo Sirainen SSL_CIPHER *value = sk_SSL_CIPHER_value(cipher_list_old, n);
0daf6ffdc0958f3dff3a81201e7cdbb1ecf0d28bTimo Sirainen if (sk_SSL_CIPHER_find(cipher_list, value) < 0) {
0daf6ffdc0958f3dff3a81201e7cdbb1ecf0d28bTimo Sirainen /* cleanup */
0daf6ffdc0958f3dff3a81201e7cdbb1ecf0d28bTimo Sirainen /* tracing */
eb1365e61674c54c7c453143356a891fb2e2b3d6Timo Sirainen "Reconfigured cipher suite will force renegotiation");
e65df911d966a0b4623e287d4669253cc46bbe0fTimo Sirainen * override of SSLVerifyDepth
e65df911d966a0b4623e287d4669253cc46bbe0fTimo Sirainen * The depth checks are handled by us manually inside the verify callback
e65df911d966a0b4623e287d4669253cc46bbe0fTimo Sirainen * function and not by OpenSSL internally (and our function is aware of
e65df911d966a0b4623e287d4669253cc46bbe0fTimo Sirainen * both the per-server and per-directory contexts). So we cannot ask
e65df911d966a0b4623e287d4669253cc46bbe0fTimo Sirainen * OpenSSL about the currently verify depth. Instead we remember it in our
e65df911d966a0b4623e287d4669253cc46bbe0fTimo Sirainen * ap_ctx attached to the SSL* of OpenSSL. We've to force the
e65df911d966a0b4623e287d4669253cc46bbe0fTimo Sirainen * renegotiation if the reconfigured/new verify depth is less than the
e65df911d966a0b4623e287d4669253cc46bbe0fTimo Sirainen * currently active/remembered verify depth (because this means more
e65df911d966a0b4623e287d4669253cc46bbe0fTimo Sirainen * restriction on the certificate chain).
1a284e27b1446cc2c0ed185dbfa4fac850a1abbdTimo Sirainen /* XXX: doesnt look like sslconn->verify_depth is actually used */
e65df911d966a0b4623e287d4669253cc46bbe0fTimo Sirainen sslconn->verify_depth = n = sc->server->auth.verify_depth;
e65df911d966a0b4623e287d4669253cc46bbe0fTimo Sirainen /* determine whether a renegotiation has to be forced */
e65df911d966a0b4623e287d4669253cc46bbe0fTimo Sirainen "Reduced client verification depth will force "
5f44975ec6c5755dd74bcd4c47a123a7242ecab3Timo Sirainen "renegotiation");
df452e9628fe8d3356c42dd644b020ea9733c0c1Timo Sirainen * override of SSLVerifyClient
df452e9628fe8d3356c42dd644b020ea9733c0c1Timo Sirainen * We force a renegotiation if the reconfigured/new verify type is
df452e9628fe8d3356c42dd644b020ea9733c0c1Timo Sirainen * stronger than the currently active verify type.
df452e9628fe8d3356c42dd644b020ea9733c0c1Timo Sirainen * The order is: none << optional_no_ca << optional << require
3e546c443055db8e8c69d43b13fb11a24f0a9b1cTimo Sirainen * Additionally the following optimization is possible here: When the
3e546c443055db8e8c69d43b13fb11a24f0a9b1cTimo Sirainen * currently active verify type is "none" but a client certificate is
3e546c443055db8e8c69d43b13fb11a24f0a9b1cTimo Sirainen * already known/present, it's enough to manually force a client
3e546c443055db8e8c69d43b13fb11a24f0a9b1cTimo Sirainen * verification but at least skip the I/O-intensive renegotation
df452e9628fe8d3356c42dd644b020ea9733c0c1Timo Sirainen /* remember old state */
5f44975ec6c5755dd74bcd4c47a123a7242ecab3Timo Sirainen /* configure new state */
3e546c443055db8e8c69d43b13fb11a24f0a9b1cTimo Sirainen if (dc->nVerifyClient == SSL_CVERIFY_REQUIRE) {
3e546c443055db8e8c69d43b13fb11a24f0a9b1cTimo Sirainen if ((dc->nVerifyClient == SSL_CVERIFY_OPTIONAL) ||
3e546c443055db8e8c69d43b13fb11a24f0a9b1cTimo Sirainen (dc->nVerifyClient == SSL_CVERIFY_OPTIONAL_NO_CA))
3e546c443055db8e8c69d43b13fb11a24f0a9b1cTimo Sirainen modssl_set_verify(ssl, verify, ssl_callback_SSLVerify);
3e546c443055db8e8c69d43b13fb11a24f0a9b1cTimo Sirainen /* determine whether we've to force a renegotiation */
e65df911d966a0b4623e287d4669253cc46bbe0fTimo Sirainen (!(verify_old & SSL_VERIFY_FAIL_IF_NO_PEER_CERT) &&
e65df911d966a0b4623e287d4669253cc46bbe0fTimo Sirainen /* optimization */
1a284e27b1446cc2c0ed185dbfa4fac850a1abbdTimo Sirainen if ((dc->nOptions & SSL_OPT_OPTRENEGOTIATE) &&
e65df911d966a0b4623e287d4669253cc46bbe0fTimo Sirainen ((peercert = SSL_get_peer_certificate(ssl)) != NULL))
df452e9628fe8d3356c42dd644b020ea9733c0c1Timo Sirainen "Changed client verification type will force "
df452e9628fe8d3356c42dd644b020ea9733c0c1Timo Sirainen "%srenegotiation",
e2b63d479f1666fef9a1d1e39c731a5cd813b437Timo Sirainen * override SSLCACertificateFile & SSLCACertificatePath
297959b63ffb7998f73d2a722a23b4dc01c52f22Timo Sirainen * This is only enabled if the SSL_set_cert_store() function
df452e9628fe8d3356c42dd644b020ea9733c0c1Timo Sirainen * is available in the ssl library. the 1.x based mod_ssl
df452e9628fe8d3356c42dd644b020ea9733c0c1Timo Sirainen * used SSL_CTX_set_cert_store which is not thread safe.
297959b63ffb7998f73d2a722a23b4dc01c52f22Timo Sirainen * check if per-dir and per-server config field are not the same.
df452e9628fe8d3356c42dd644b020ea9733c0c1Timo Sirainen * if f is defined in per-dir and not defined in per-server
df452e9628fe8d3356c42dd644b020ea9733c0c1Timo Sirainen * or f is defined in both but not the equal ...
e2b63d479f1666fef9a1d1e39c731a5cd813b437Timo Sirainen (dc->f && (!sc->f || (sc->f && strNE(dc->f, sc->f))))
e2b63d479f1666fef9a1d1e39c731a5cd813b437Timo Sirainen const char *ca_file = MODSSL_CFG_CA(szCACertificateFile);
e2b63d479f1666fef9a1d1e39c731a5cd813b437Timo Sirainen const char *ca_path = MODSSL_CFG_CA(szCACertificatePath);
df452e9628fe8d3356c42dd644b020ea9733c0c1Timo Sirainen if (!X509_STORE_load_locations(cert_store, ca_file, ca_path)) {
df452e9628fe8d3356c42dd644b020ea9733c0c1Timo Sirainen "Unable to reconfigure verify locations "
df452e9628fe8d3356c42dd644b020ea9733c0c1Timo Sirainen "for client authentication");
df452e9628fe8d3356c42dd644b020ea9733c0c1Timo Sirainen ssl_log_ssl_error(APLOG_MARK, APLOG_ERR, r->server);
e15b305e90c9834734ccf35ed78f0ad29d570ee9Timo Sirainen /* SSL_free will free cert_store */
9fb018dea4e2073639249ea8a14ae27cab2c0aacTimo Sirainen if (!(ca_list = ssl_init_FindCAList(r->server, r->pool,
9fb018dea4e2073639249ea8a14ae27cab2c0aacTimo Sirainen ap_log_error(APLOG_MARK, APLOG_ERR, 0, r->server,
9fb018dea4e2073639249ea8a14ae27cab2c0aacTimo Sirainen "Unable to determine list of available "
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen "CA certificates for client authentication");
b8eb60a9ba83e2f3f6d969e810553eb937be2128Timo Sirainen "Changed client verification locations will force "
9fb018dea4e2073639249ea8a14ae27cab2c0aacTimo Sirainen "renegotiation");
df452e9628fe8d3356c42dd644b020ea9733c0c1Timo Sirainen#endif /* HAVE_SSL_SET_CERT_STORE */
9fb018dea4e2073639249ea8a14ae27cab2c0aacTimo Sirainen /* If a renegotiation is now required for this location, and the
9fb018dea4e2073639249ea8a14ae27cab2c0aacTimo Sirainen * request includes a message body (and the client has not
9fb018dea4e2073639249ea8a14ae27cab2c0aacTimo Sirainen * requested a "100 Continue" response), then the client will be
f46885a5b78b15a8d2419f6e5d13b643bd85e41fTimo Sirainen * streaming the request body over the wire already. In that
9fb018dea4e2073639249ea8a14ae27cab2c0aacTimo Sirainen * case, it is not possible to stop and perform a new SSL
9fb018dea4e2073639249ea8a14ae27cab2c0aacTimo Sirainen * handshake immediately; once the SSL library moves to the
9fb018dea4e2073639249ea8a14ae27cab2c0aacTimo Sirainen * "accept" state, it will reject the SSL packets which the client
9fb018dea4e2073639249ea8a14ae27cab2c0aacTimo Sirainen * is sending for the request body.
&& !r->expecting_100) {
int rv;
if (rv) {
return rv;
if (renegotiate) {
if (renegotiate_quick) {
return HTTP_FORBIDDEN;
if (!(cert_store ||
return HTTP_FORBIDDEN;
if (!cert) {
if (depth >= 0) {
(char *)ssl);
(unsigned char *)&id,
sizeof(id));
return HTTP_FORBIDDEN;
return HTTP_FORBIDDEN;
return HTTP_FORBIDDEN;
if (do_verify) {
return HTTP_FORBIDDEN;
if (cipher_list) {
r->filename,
return HTTP_FORBIDDEN;
if (ok < 0) {
return HTTP_FORBIDDEN;
r->filename,
return HTTP_FORBIDDEN;
return DECLINED;
char *clientdn;
return HTTP_FORBIDDEN;
if (!ap_is_initial_req(r)) {
return DECLINED;
auth_line++;
return HTTP_FORBIDDEN;
return DECLINED;
NULL);
return DECLINED;
return HTTP_FORBIDDEN;
return DECLINED;
static const char *ssl_hook_Fixup_vars[] = {
#ifndef OPENSSL_NO_TLSEXT
const char* servername;
&& !r->main) {
if (!(((sc->enabled == SSL_ENABLED_TRUE) || (sc->enabled == SSL_ENABLED_OPTIONAL)) && sslconn && (ssl = sslconn->ssl))) {
return DECLINED;
#ifndef OPENSSL_NO_TLSEXT
for (i = 0; ssl_hook_Fixup_vars[i]; i++) {
r, var);
if (val) {
return DECLINED;
int idx;
switch (keylen) {
int idx;
switch (keylen) {
errdepth);
return TRUE;
if (ok) {
#ifdef HAVE_OCSP
if (!ok) {
if (!ok) {
return ok;
int i, n, rc;
return ok;
#ifdef OPENSSL_VERSION_NUMBER
if (pubkey)
if (rc <= 0) {
return FALSE;
return FALSE;
return FALSE;
return FALSE;
return ok;
#define SSLPROXY_CERT_CB_LOG_FMT \
const char *msg)
char *dn;
return FALSE;
return TRUE;
return TRUE;
return FALSE;
const char *request,
unsigned char *id,
unsigned int idlen,
const char *status,
const char *result,
long timeout)
if (timeout) {
unsigned char *id;
unsigned int idlen;
unsigned char *id,
*do_copy = 0;
return session;
server_rec *s;
unsigned char *id;
unsigned int idlen;
conn_rec *c;
server_rec *s;
s = c->base_server;
if (rc == 0) {
else if (rc < 0) {