source: mod_gnutls/src/mod_gnutls.c @ c6dda6d

debian/masterdebian/stretch-backportsupstream
Last change on this file since c6dda6d was c6dda6d, checked in by Thomas Klute <thomas2.klute@…>, 3 years ago

Rate limit OCSP requests

Retries after failed OCSP requests must be rate limited. If the
responder is overloaded or buggy we don't want to add too much more
load, and if a MITM is messing with requests a repetition loop might
end up being a self-inflicted denial of service.

The minimum time to wait between retries can be configured using the
GnuTLSOCSPFailureTimeout directive.

  • Property mode set to 100644
File size: 10.2 KB
Line 
1/**
2 *  Copyright 2004-2005 Paul Querna
3 *  Copyright 2008, 2014 Nikos Mavrogiannopoulos
4 *  Copyright 2011 Dash Shendy
5 *  Copyright 2015-2016 Thomas Klute
6 *
7 *  Licensed under the Apache License, Version 2.0 (the "License");
8 *  you may not use this file except in compliance with the License.
9 *  You may obtain a copy of the License at
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 *  Unless required by applicable law or agreed to in writing, software
14 *  distributed under the License is distributed on an "AS IS" BASIS,
15 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 *  See the License for the specific language governing permissions and
17 *  limitations under the License.
18 *
19 */
20
21#include "mod_gnutls.h"
22#include "gnutls_ocsp.h"
23
24#ifdef APLOG_USE_MODULE
25APLOG_USE_MODULE(gnutls);
26#endif
27
28static void gnutls_hooks(apr_pool_t * p __attribute__((unused)))
29{
30    /* Try Run Post-Config Hook After mod_proxy */
31    static const char * const aszPre[] = { "mod_proxy.c", NULL };
32    ap_hook_post_config(mgs_hook_post_config, aszPre, NULL,
33                        APR_HOOK_REALLY_LAST);
34    /* HTTP Scheme Hook */
35    ap_hook_http_scheme(mgs_hook_http_scheme, NULL, NULL, APR_HOOK_MIDDLE);
36    /* Default Port Hook */
37    ap_hook_default_port(mgs_hook_default_port, NULL, NULL, APR_HOOK_MIDDLE);
38    /* Pre-Connect Hook */
39    ap_hook_pre_connection(mgs_hook_pre_connection, NULL, NULL,
40                           APR_HOOK_MIDDLE);
41    /* Pre-Config Hook */
42    ap_hook_pre_config(mgs_hook_pre_config, NULL, NULL,
43                       APR_HOOK_MIDDLE);
44    /* Child-Init Hook */
45    ap_hook_child_init(mgs_hook_child_init, NULL, NULL,
46                       APR_HOOK_MIDDLE);
47    /* Authentication Hook */
48    ap_hook_access_checker(mgs_hook_authz, NULL, NULL,
49                           APR_HOOK_REALLY_FIRST);
50    /* Fixups Hook */
51    ap_hook_fixups(mgs_hook_fixups, NULL, NULL, APR_HOOK_REALLY_FIRST);
52
53    /* TODO: HTTP Upgrade Filter */
54    /* ap_register_output_filter ("UPGRADE_FILTER",
55     *          ssl_io_filter_Upgrade, NULL, AP_FTYPE_PROTOCOL + 5);
56     */
57
58    /* Input Filter */
59    ap_register_input_filter(GNUTLS_INPUT_FILTER_NAME, mgs_filter_input,
60                             NULL, AP_FTYPE_CONNECTION + 5);
61    /* Output Filter */
62    ap_register_output_filter(GNUTLS_OUTPUT_FILTER_NAME, mgs_filter_output,
63                              NULL, AP_FTYPE_CONNECTION + 5);
64
65    /* mod_proxy calls these functions */
66    APR_REGISTER_OPTIONAL_FN(ssl_proxy_enable);
67    APR_REGISTER_OPTIONAL_FN(ssl_engine_disable);
68
69    /* mod_rewrite calls this function to detect HTTPS */
70    APR_REGISTER_OPTIONAL_FN(ssl_is_https);
71}
72
73
74
75/*
76 * mod_rewrite calls this function to fill %{HTTPS}. A non-zero return
77 * value means that HTTPS is in use.
78 */
79int ssl_is_https(conn_rec *c)
80{
81    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
82        ap_get_module_config(c->base_server->module_config, &gnutls_module);
83    mgs_handle_t *ctxt = (mgs_handle_t *)
84        ap_get_module_config(c->conn_config, &gnutls_module);
85
86    if(sc->enabled == GNUTLS_ENABLED_FALSE
87       || ctxt == NULL
88       || ctxt->enabled == GNUTLS_ENABLED_FALSE)
89    {
90        /* SSL/TLS Disabled or Plain HTTP Connection Detected */
91        return 0;
92    }
93    /* Connection is Using SSL/TLS */
94    return 1;
95}
96
97
98
99int ssl_engine_disable(conn_rec *c)
100{
101    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
102        ap_get_module_config(c->base_server->module_config, &gnutls_module);
103    if(sc->enabled == GNUTLS_ENABLED_FALSE) {
104        return 1;
105    }
106
107    /* disable TLS for this connection */
108    mgs_handle_t *ctxt = (mgs_handle_t *)
109        ap_get_module_config(c->conn_config, &gnutls_module);
110    if (ctxt == NULL)
111    {
112        ctxt = apr_pcalloc(c->pool, sizeof (*ctxt));
113        ap_set_module_config(c->conn_config, &gnutls_module, ctxt);
114    }
115    ctxt->enabled = GNUTLS_ENABLED_FALSE;
116    ctxt->is_proxy = GNUTLS_ENABLED_TRUE;
117
118    if (c->input_filters)
119        ap_remove_input_filter(c->input_filters);
120    if (c->output_filters)
121        ap_remove_output_filter(c->output_filters);
122
123    return 1;
124}
125
126int ssl_proxy_enable(conn_rec *c)
127{
128    /* check if TLS proxy support is enabled */
129    mgs_srvconf_rec *sc = (mgs_srvconf_rec *)
130        ap_get_module_config(c->base_server->module_config, &gnutls_module);
131    if (sc->proxy_enabled != GNUTLS_ENABLED_TRUE)
132    {
133        ap_log_cerror(APLOG_MARK, APLOG_ERR, 0, c,
134                      "%s: mod_proxy requested TLS proxy, but not enabled "
135                      "for %s", __func__, sc->cert_cn);
136        return 0;
137    }
138
139    /* enable TLS for this connection */
140    mgs_handle_t *ctxt = (mgs_handle_t *)
141        ap_get_module_config(c->conn_config, &gnutls_module);
142    if (ctxt == NULL)
143    {
144        ctxt = apr_pcalloc(c->pool, sizeof (*ctxt));
145        ap_set_module_config(c->conn_config, &gnutls_module, ctxt);
146    }
147    ctxt->enabled = GNUTLS_ENABLED_TRUE;
148    ctxt->is_proxy = GNUTLS_ENABLED_TRUE;
149    return 1;
150}
151
152static const command_rec mgs_config_cmds[] = {
153    AP_INIT_FLAG("GnuTLSProxyEngine", mgs_set_proxy_engine,
154    NULL,
155    RSRC_CONF | OR_AUTHCFG,
156    "Enable TLS Proxy Engine"),
157    AP_INIT_TAKE1("GnuTLSP11Module", mgs_set_p11_module,
158    NULL,
159    RSRC_CONF,
160    "Load this specific PKCS #11 provider library"),
161    AP_INIT_RAW_ARGS("GnuTLSPIN", mgs_set_pin,
162    NULL,
163    RSRC_CONF,
164    "The PIN to use in case of encrypted keys or PKCS #11 tokens."),
165    AP_INIT_RAW_ARGS("GnuTLSSRKPIN", mgs_set_srk_pin,
166    NULL,
167    RSRC_CONF,
168    "The SRK PIN to use in case of TPM keys."),
169    AP_INIT_TAKE1("GnuTLSClientVerify", mgs_set_client_verify,
170    NULL,
171    RSRC_CONF | OR_AUTHCFG,
172    "Set Verification Requirements of the Client Certificate"),
173    AP_INIT_TAKE1("GnuTLSClientVerifyMethod", mgs_set_client_verify_method,
174    NULL,
175    RSRC_CONF,
176    "Set Verification Method of the Client Certificate"),
177    AP_INIT_TAKE1("GnuTLSClientCAFile", mgs_set_client_ca_file,
178    NULL,
179    RSRC_CONF,
180    "Set the CA File to verify Client Certificates"),
181    AP_INIT_TAKE1("GnuTLSX509CAFile", mgs_set_client_ca_file,
182    NULL,
183    RSRC_CONF,
184    "Set the CA File to verify Client Certificates"),
185    AP_INIT_TAKE1("GnuTLSPGPKeyringFile", mgs_set_keyring_file,
186    NULL,
187    RSRC_CONF,
188    "Set the Keyring File to verify Client Certificates"),
189    AP_INIT_TAKE1("GnuTLSDHFile", mgs_set_dh_file,
190    NULL,
191    RSRC_CONF,
192    "Set the file to read Diffie Hellman parameters from"),
193    AP_INIT_TAKE1("GnuTLSCertificateFile", mgs_set_cert_file,
194    NULL,
195    RSRC_CONF,
196    "TLS Server X509 Certificate file"),
197    AP_INIT_TAKE1("GnuTLSKeyFile", mgs_set_key_file,
198    NULL,
199    RSRC_CONF,
200    "TLS Server X509 Private Key file"),
201    AP_INIT_TAKE1("GnuTLSX509CertificateFile", mgs_set_cert_file,
202    NULL,
203    RSRC_CONF,
204    "TLS Server X509 Certificate file"),
205    AP_INIT_TAKE1("GnuTLSX509KeyFile", mgs_set_key_file,
206    NULL,
207    RSRC_CONF,
208    "TLS Server X509 Private Key file"),
209    AP_INIT_TAKE1("GnuTLSPGPCertificateFile", mgs_set_pgpcert_file,
210    NULL,
211    RSRC_CONF,
212    "TLS Server PGP Certificate file"),
213    AP_INIT_TAKE1("GnuTLSPGPKeyFile", mgs_set_pgpkey_file,
214    NULL,
215    RSRC_CONF,
216    "TLS Server PGP Private key file"),
217#ifdef ENABLE_SRP
218    AP_INIT_TAKE1("GnuTLSSRPPasswdFile", mgs_set_srp_tpasswd_file,
219    NULL,
220    RSRC_CONF,
221    "TLS Server SRP Password Conf file"),
222    AP_INIT_TAKE1("GnuTLSSRPPasswdConfFile",
223    mgs_set_srp_tpasswd_conf_file,
224    NULL,
225    RSRC_CONF,
226    "TLS Server SRP Parameters file"),
227#endif
228    AP_INIT_TAKE1("GnuTLSCacheTimeout", mgs_set_timeout,
229    NULL,
230    RSRC_CONF,
231    "Cache Timeout"),
232    AP_INIT_TAKE12("GnuTLSCache", mgs_set_cache,
233    NULL,
234    RSRC_CONF,
235    "Cache Configuration"),
236    AP_INIT_FLAG("GnuTLSSessionTickets", mgs_set_tickets,
237    NULL,
238    RSRC_CONF,
239    "Session Tickets Configuration"),
240    AP_INIT_RAW_ARGS("GnuTLSPriorities", mgs_set_priorities,
241    NULL,
242    RSRC_CONF,
243    "The priorities to enable (ciphers, Key exchange, macs, compression)."),
244    AP_INIT_FLAG("GnuTLSEnable", mgs_set_enabled,
245    NULL,
246    RSRC_CONF,
247    "Whether this server has GnuTLS Enabled. Default: Off"),
248    AP_INIT_TAKE1("GnuTLSExportCertificates",
249    mgs_set_export_certificates_size,
250    NULL,
251    RSRC_CONF,
252    "Max size to export PEM encoded certificates to CGIs (or off to disable). Default: off"),
253    AP_INIT_TAKE1("GnuTLSProxyKeyFile", mgs_store_cred_path,
254    NULL,
255    RSRC_CONF,
256    "X509 client private file for proxy connections"),
257    AP_INIT_TAKE1("GnuTLSProxyCertificateFile", mgs_store_cred_path,
258    NULL,
259    RSRC_CONF,
260    "X509 client certificate file for proxy connections"),
261    AP_INIT_TAKE1("GnuTLSProxyCAFile", mgs_store_cred_path,
262    NULL,
263    RSRC_CONF,
264    "X509 trusted CA file for proxy connections"),
265    AP_INIT_TAKE1("GnuTLSProxyCRLFile", mgs_store_cred_path,
266    NULL,
267    RSRC_CONF,
268    "X509 CRL file for proxy connections"),
269    AP_INIT_RAW_ARGS("GnuTLSProxyPriorities", mgs_set_priorities,
270    NULL,
271    RSRC_CONF,
272    "The priorities to enable for proxy connections (ciphers, key exchange, "
273    "MACs, compression)."),
274    AP_INIT_FLAG("GnuTLSOCSPStapling", mgs_ocsp_stapling_enable,
275                 NULL, RSRC_CONF,
276                 "EXPERIMENTAL: Enable OCSP stapling"),
277    AP_INIT_TAKE1("GnuTLSOCSPResponseFile", mgs_store_ocsp_response_path,
278                  NULL, RSRC_CONF,
279                  "EXPERIMENTAL: Read OCSP response for stapling from this "
280                  "file instead of sending a request over HTTP (must be "
281                  "updated externally)"),
282    AP_INIT_TAKE1("GnuTLSOCSPGraceTime", mgs_set_timeout,
283                  NULL, RSRC_CONF,
284                  "EXPERIMENTAL: Replace cached OCSP responses this many "
285                  "seconds before they expire"),
286    AP_INIT_TAKE1("GnuTLSOCSPFailureTimeout", mgs_set_timeout,
287                  NULL, RSRC_CONF,
288                  "EXPERIMENTAL: Wait this many seconds before retrying a "
289                  "failed OCSP request"),
290#ifdef __clang__
291    /* Workaround for this clang bug:
292     * https://llvm.org/bugs/show_bug.cgi?id=21689 */
293    {},
294#else
295    { NULL },
296#endif
297};
298
299module AP_MODULE_DECLARE_DATA gnutls_module = {
300    STANDARD20_MODULE_STUFF,
301    .create_dir_config = mgs_config_dir_create,
302    .merge_dir_config = mgs_config_dir_merge,
303    .create_server_config = mgs_config_server_create,
304    .merge_server_config = mgs_config_server_merge,
305    .cmds = mgs_config_cmds,
306    .register_hooks = gnutls_hooks
307};
Note: See TracBrowser for help on using the repository browser.