1 /* Copyright 2015 greenbytes GmbH (https://www.greenbytes.de)
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
18 #include <apr_strings.h>
19 #include <apr_optional.h>
20 #include <apr_optional_hooks.h>
23 #include <http_core.h>
24 #include <http_config.h>
25 #include <http_connection.h>
26 #include <http_protocol.h>
29 #include "h2_private.h"
31 #include "h2_stream.h"
33 #include "h2_config.h"
38 const char *h2_tls_protos[] = {
42 const char *h2_clear_protos[] = {
46 const char *H2_MAGIC_TOKEN = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n";
48 /*******************************************************************************
49 * The optional mod_ssl functions we need.
51 APR_DECLARE_OPTIONAL_FN(int, ssl_engine_disable, (conn_rec*));
52 APR_DECLARE_OPTIONAL_FN(int, ssl_is_https, (conn_rec*));
54 static int (*opt_ssl_engine_disable)(conn_rec*);
55 static int (*opt_ssl_is_https)(conn_rec*);
56 /*******************************************************************************
59 APR_DECLARE_OPTIONAL_FN(char *, ssl_var_lookup,
60 (apr_pool_t *, server_rec *,
61 conn_rec *, request_rec *,
63 static char *(*opt_ssl_var_lookup)(apr_pool_t *, server_rec *,
64 conn_rec *, request_rec *,
68 /*******************************************************************************
71 static const char *h2_err_descr[] = {
77 "stream closed", /* 0x5 */
82 "connect error", /* 0xa */
84 "inadequate security",
88 const char *h2_h2_err_description(unsigned int h2_error)
90 if (h2_error < (sizeof(h2_err_descr)/sizeof(h2_err_descr[0]))) {
91 return h2_err_descr[h2_error];
93 return "unknown http/2 errotr code";
96 /*******************************************************************************
97 * Check connection security requirements of RFC 7540
101 * Black Listed Ciphers from RFC 7549 Appendix A
104 static const char *RFC7540_names[] = {
105 /* ciphers with NULL encrpytion */
106 "NULL-MD5", /* TLS_NULL_WITH_NULL_NULL */
107 /* same */ /* TLS_RSA_WITH_NULL_MD5 */
108 "NULL-SHA", /* TLS_RSA_WITH_NULL_SHA */
109 "NULL-SHA256", /* TLS_RSA_WITH_NULL_SHA256 */
110 "PSK-NULL-SHA", /* TLS_PSK_WITH_NULL_SHA */
111 "DHE-PSK-NULL-SHA", /* TLS_DHE_PSK_WITH_NULL_SHA */
112 "RSA-PSK-NULL-SHA", /* TLS_RSA_PSK_WITH_NULL_SHA */
113 "PSK-NULL-SHA256", /* TLS_PSK_WITH_NULL_SHA256 */
114 "PSK-NULL-SHA384", /* TLS_PSK_WITH_NULL_SHA384 */
115 "DHE-PSK-NULL-SHA256", /* TLS_DHE_PSK_WITH_NULL_SHA256 */
116 "DHE-PSK-NULL-SHA384", /* TLS_DHE_PSK_WITH_NULL_SHA384 */
117 "RSA-PSK-NULL-SHA256", /* TLS_RSA_PSK_WITH_NULL_SHA256 */
118 "RSA-PSK-NULL-SHA384", /* TLS_RSA_PSK_WITH_NULL_SHA384 */
119 "ECDH-ECDSA-NULL-SHA", /* TLS_ECDH_ECDSA_WITH_NULL_SHA */
120 "ECDHE-ECDSA-NULL-SHA", /* TLS_ECDHE_ECDSA_WITH_NULL_SHA */
121 "ECDH-RSA-NULL-SHA", /* TLS_ECDH_RSA_WITH_NULL_SHA */
122 "ECDHE-RSA-NULL-SHA", /* TLS_ECDHE_RSA_WITH_NULL_SHA */
123 "AECDH-NULL-SHA", /* TLS_ECDH_anon_WITH_NULL_SHA */
124 "ECDHE-PSK-NULL-SHA", /* TLS_ECDHE_PSK_WITH_NULL_SHA */
125 "ECDHE-PSK-NULL-SHA256", /* TLS_ECDHE_PSK_WITH_NULL_SHA256 */
126 "ECDHE-PSK-NULL-SHA384", /* TLS_ECDHE_PSK_WITH_NULL_SHA384 */
128 /* DES/3DES ciphers */
129 "PSK-3DES-EDE-CBC-SHA", /* TLS_PSK_WITH_3DES_EDE_CBC_SHA */
130 "DHE-PSK-3DES-EDE-CBC-SHA", /* TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA */
131 "RSA-PSK-3DES-EDE-CBC-SHA", /* TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA */
132 "ECDH-ECDSA-DES-CBC3-SHA", /* TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA */
133 "ECDHE-ECDSA-DES-CBC3-SHA", /* TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA */
134 "ECDH-RSA-DES-CBC3-SHA", /* TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA */
135 "ECDHE-RSA-DES-CBC3-SHA", /* TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA */
136 "AECDH-DES-CBC3-SHA", /* TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA */
137 "SRP-3DES-EDE-CBC-SHA", /* TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA */
138 "SRP-RSA-3DES-EDE-CBC-SHA", /* TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA */
139 "SRP-DSS-3DES-EDE-CBC-SHA", /* TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA */
140 "ECDHE-PSK-3DES-EDE-CBC-SHA", /* TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA */
141 "DES-CBC-SHA", /* TLS_RSA_WITH_DES_CBC_SHA */
142 "DES-CBC3-SHA", /* TLS_RSA_WITH_3DES_EDE_CBC_SHA */
143 "DHE-DSS-DES-CBC3-SHA", /* TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA */
144 "DHE-RSA-DES-CBC-SHA", /* TLS_DHE_RSA_WITH_DES_CBC_SHA */
145 "DHE-RSA-DES-CBC3-SHA", /* TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA */
146 "ADH-DES-CBC-SHA", /* TLS_DH_anon_WITH_DES_CBC_SHA */
147 "ADH-DES-CBC3-SHA", /* TLS_DH_anon_WITH_3DES_EDE_CBC_SHA */
148 "EXP-DH-DSS-DES-CBC-SHA", /* TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA */
149 "DH-DSS-DES-CBC-SHA", /* TLS_DH_DSS_WITH_DES_CBC_SHA */
150 "DH-DSS-DES-CBC3-SHA", /* TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA */
151 "EXP-DH-RSA-DES-CBC-SHA", /* TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA */
152 "DH-RSA-DES-CBC-SHA", /* TLS_DH_RSA_WITH_DES_CBC_SHA */
153 "DH-RSA-DES-CBC3-SHA", /* TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA */
155 /* blacklisted EXPORT ciphers */
156 "EXP-RC4-MD5", /* TLS_RSA_EXPORT_WITH_RC4_40_MD5 */
157 "EXP-RC2-CBC-MD5", /* TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 */
158 "EXP-DES-CBC-SHA", /* TLS_RSA_EXPORT_WITH_DES40_CBC_SHA */
159 "EXP-DHE-DSS-DES-CBC-SHA", /* TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA */
160 "EXP-DHE-RSA-DES-CBC-SHA", /* TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA */
161 "EXP-ADH-DES-CBC-SHA", /* TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA */
162 "EXP-ADH-RC4-MD5", /* TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 */
164 /* blacklisted RC4 encryption */
165 "RC4-MD5", /* TLS_RSA_WITH_RC4_128_MD5 */
166 "RC4-SHA", /* TLS_RSA_WITH_RC4_128_SHA */
167 "ADH-RC4-MD5", /* TLS_DH_anon_WITH_RC4_128_MD5 */
168 "KRB5-RC4-SHA", /* TLS_KRB5_WITH_RC4_128_SHA */
169 "KRB5-RC4-MD5", /* TLS_KRB5_WITH_RC4_128_MD5 */
170 "EXP-KRB5-RC4-SHA", /* TLS_KRB5_EXPORT_WITH_RC4_40_SHA */
171 "EXP-KRB5-RC4-MD5", /* TLS_KRB5_EXPORT_WITH_RC4_40_MD5 */
172 "PSK-RC4-SHA", /* TLS_PSK_WITH_RC4_128_SHA */
173 "DHE-PSK-RC4-SHA", /* TLS_DHE_PSK_WITH_RC4_128_SHA */
174 "RSA-PSK-RC4-SHA", /* TLS_RSA_PSK_WITH_RC4_128_SHA */
175 "ECDH-ECDSA-RC4-SHA", /* TLS_ECDH_ECDSA_WITH_RC4_128_SHA */
176 "ECDHE-ECDSA-RC4-SHA", /* TLS_ECDHE_ECDSA_WITH_RC4_128_SHA */
177 "ECDH-RSA-RC4-SHA", /* TLS_ECDH_RSA_WITH_RC4_128_SHA */
178 "ECDHE-RSA-RC4-SHA", /* TLS_ECDHE_RSA_WITH_RC4_128_SHA */
179 "AECDH-RC4-SHA", /* TLS_ECDH_anon_WITH_RC4_128_SHA */
180 "ECDHE-PSK-RC4-SHA", /* TLS_ECDHE_PSK_WITH_RC4_128_SHA */
182 /* blacklisted AES128 encrpytion ciphers */
183 "AES128-SHA256", /* TLS_RSA_WITH_AES_128_CBC_SHA */
184 "DH-DSS-AES128-SHA", /* TLS_DH_DSS_WITH_AES_128_CBC_SHA */
185 "DH-RSA-AES128-SHA", /* TLS_DH_RSA_WITH_AES_128_CBC_SHA */
186 "DHE-DSS-AES128-SHA", /* TLS_DHE_DSS_WITH_AES_128_CBC_SHA */
187 "DHE-RSA-AES128-SHA", /* TLS_DHE_RSA_WITH_AES_128_CBC_SHA */
188 "ADH-AES128-SHA", /* TLS_DH_anon_WITH_AES_128_CBC_SHA */
189 "AES128-SHA256", /* TLS_RSA_WITH_AES_128_CBC_SHA256 */
190 "DH-DSS-AES128-SHA256", /* TLS_DH_DSS_WITH_AES_128_CBC_SHA256 */
191 "DH-RSA-AES128-SHA256", /* TLS_DH_RSA_WITH_AES_128_CBC_SHA256 */
192 "DHE-DSS-AES128-SHA256", /* TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 */
193 "DHE-RSA-AES128-SHA256", /* TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 */
194 "ECDH-ECDSA-AES128-SHA", /* TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA */
195 "ECDHE-ECDSA-AES128-SHA", /* TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA */
196 "ECDH-RSA-AES128-SHA", /* TLS_ECDH_RSA_WITH_AES_128_CBC_SHA */
197 "ECDHE-RSA-AES128-SHA", /* TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA */
198 "AECDH-AES128-SHA", /* TLS_ECDH_anon_WITH_AES_128_CBC_SHA */
199 "ECDHE-ECDSA-AES128-SHA256", /* TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 */
200 "ECDH-ECDSA-AES128-SHA256", /* TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 */
201 "ECDHE-RSA-AES128-SHA256", /* TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 */
202 "ECDH-RSA-AES128-SHA256", /* TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 */
203 "ADH-AES128-SHA256", /* TLS_DH_anon_WITH_AES_128_CBC_SHA256 */
204 "PSK-AES128-CBC-SHA", /* TLS_PSK_WITH_AES_128_CBC_SHA */
205 "DHE-PSK-AES128-CBC-SHA", /* TLS_DHE_PSK_WITH_AES_128_CBC_SHA */
206 "RSA-PSK-AES128-CBC-SHA", /* TLS_RSA_PSK_WITH_AES_128_CBC_SHA */
207 "PSK-AES128-CBC-SHA256", /* TLS_PSK_WITH_AES_128_CBC_SHA256 */
208 "DHE-PSK-AES128-CBC-SHA256", /* TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 */
209 "RSA-PSK-AES128-CBC-SHA256", /* TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 */
210 "ECDHE-PSK-AES128-CBC-SHA", /* TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA */
211 "ECDHE-PSK-AES128-CBC-SHA256", /* TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 */
212 "AES128-CCM", /* TLS_RSA_WITH_AES_128_CCM */
213 "AES128-CCM8", /* TLS_RSA_WITH_AES_128_CCM_8 */
214 "PSK-AES128-CCM", /* TLS_PSK_WITH_AES_128_CCM */
215 "PSK-AES128-CCM8", /* TLS_PSK_WITH_AES_128_CCM_8 */
216 "AES128-GCM-SHA256", /* TLS_RSA_WITH_AES_128_GCM_SHA256 */
217 "DH-RSA-AES128-GCM-SHA256", /* TLS_DH_RSA_WITH_AES_128_GCM_SHA256 */
218 "DH-DSS-AES128-GCM-SHA256", /* TLS_DH_DSS_WITH_AES_128_GCM_SHA256 */
219 "ADH-AES128-GCM-SHA256", /* TLS_DH_anon_WITH_AES_128_GCM_SHA256 */
220 "PSK-AES128-GCM-SHA256", /* TLS_PSK_WITH_AES_128_GCM_SHA256 */
221 "RSA-PSK-AES128-GCM-SHA256", /* TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 */
222 "ECDH-ECDSA-AES128-GCM-SHA256", /* TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 */
223 "ECDH-RSA-AES128-GCM-SHA256", /* TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 */
224 "SRP-AES-128-CBC-SHA", /* TLS_SRP_SHA_WITH_AES_128_CBC_SHA */
225 "SRP-RSA-AES-128-CBC-SHA", /* TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA */
226 "SRP-DSS-AES-128-CBC-SHA", /* TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA */
228 /* blacklisted AES256 encrpytion ciphers */
229 "AES256-SHA", /* TLS_RSA_WITH_AES_256_CBC_SHA */
230 "DH-DSS-AES256-SHA", /* TLS_DH_DSS_WITH_AES_256_CBC_SHA */
231 "DH-RSA-AES256-SHA", /* TLS_DH_RSA_WITH_AES_256_CBC_SHA */
232 "DHE-DSS-AES256-SHA", /* TLS_DHE_DSS_WITH_AES_256_CBC_SHA */
233 "DHE-RSA-AES256-SHA", /* TLS_DHE_RSA_WITH_AES_256_CBC_SHA */
234 "ADH-AES256-SHA", /* TLS_DH_anon_WITH_AES_256_CBC_SHA */
235 "AES256-SHA256", /* TLS_RSA_WITH_AES_256_CBC_SHA256 */
236 "DH-DSS-AES256-SHA256", /* TLS_DH_DSS_WITH_AES_256_CBC_SHA256 */
237 "DH-RSA-AES256-SHA256", /* TLS_DH_RSA_WITH_AES_256_CBC_SHA256 */
238 "DHE-DSS-AES256-SHA256", /* TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 */
239 "DHE-RSA-AES256-SHA256", /* TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 */
240 "ADH-AES256-SHA256", /* TLS_DH_anon_WITH_AES_256_CBC_SHA256 */
241 "ECDH-ECDSA-AES256-SHA", /* TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA */
242 "ECDHE-ECDSA-AES256-SHA", /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA */
243 "ECDH-RSA-AES256-SHA", /* TLS_ECDH_RSA_WITH_AES_256_CBC_SHA */
244 "ECDHE-RSA-AES256-SHA", /* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA */
245 "AECDH-AES256-SHA", /* TLS_ECDH_anon_WITH_AES_256_CBC_SHA */
246 "ECDHE-ECDSA-AES256-SHA384", /* TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 */
247 "ECDH-ECDSA-AES256-SHA384", /* TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 */
248 "ECDHE-RSA-AES256-SHA384", /* TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 */
249 "ECDH-RSA-AES256-SHA384", /* TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 */
250 "PSK-AES256-CBC-SHA", /* TLS_PSK_WITH_AES_256_CBC_SHA */
251 "DHE-PSK-AES256-CBC-SHA", /* TLS_DHE_PSK_WITH_AES_256_CBC_SHA */
252 "RSA-PSK-AES256-CBC-SHA", /* TLS_RSA_PSK_WITH_AES_256_CBC_SHA */
253 "PSK-AES256-CBC-SHA384", /* TLS_PSK_WITH_AES_256_CBC_SHA384 */
254 "DHE-PSK-AES256-CBC-SHA384", /* TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 */
255 "RSA-PSK-AES256-CBC-SHA384", /* TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 */
256 "ECDHE-PSK-AES256-CBC-SHA", /* TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA */
257 "ECDHE-PSK-AES256-CBC-SHA384", /* TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 */
258 "SRP-AES-256-CBC-SHA", /* TLS_SRP_SHA_WITH_AES_256_CBC_SHA */
259 "SRP-RSA-AES-256-CBC-SHA", /* TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA */
260 "SRP-DSS-AES-256-CBC-SHA", /* TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA */
261 "AES256-CCM", /* TLS_RSA_WITH_AES_256_CCM */
262 "AES256-CCM8", /* TLS_RSA_WITH_AES_256_CCM_8 */
263 "PSK-AES256-CCM", /* TLS_PSK_WITH_AES_256_CCM */
264 "PSK-AES256-CCM8", /* TLS_PSK_WITH_AES_256_CCM_8 */
265 "AES256-GCM-SHA384", /* TLS_RSA_WITH_AES_256_GCM_SHA384 */
266 "DH-RSA-AES256-GCM-SHA384", /* TLS_DH_RSA_WITH_AES_256_GCM_SHA384 */
267 "DH-DSS-AES256-GCM-SHA384", /* TLS_DH_DSS_WITH_AES_256_GCM_SHA384 */
268 "ADH-AES256-GCM-SHA384", /* TLS_DH_anon_WITH_AES_256_GCM_SHA384 */
269 "PSK-AES256-GCM-SHA384", /* TLS_PSK_WITH_AES_256_GCM_SHA384 */
270 "RSA-PSK-AES256-GCM-SHA384", /* TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 */
271 "ECDH-ECDSA-AES256-GCM-SHA384", /* TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 */
272 "ECDH-RSA-AES256-GCM-SHA384", /* TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 */
274 /* blacklisted CAMELLIA128 encrpytion ciphers */
275 "CAMELLIA128-SHA", /* TLS_RSA_WITH_CAMELLIA_128_CBC_SHA */
276 "DH-DSS-CAMELLIA128-SHA", /* TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA */
277 "DH-RSA-CAMELLIA128-SHA", /* TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA */
278 "DHE-DSS-CAMELLIA128-SHA", /* TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA */
279 "DHE-RSA-CAMELLIA128-SHA", /* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA */
280 "ADH-CAMELLIA128-SHA", /* TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA */
281 "ECDHE-ECDSA-CAMELLIA128-SHA256", /* TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 */
282 "ECDH-ECDSA-CAMELLIA128-SHA256", /* TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 */
283 "ECDHE-RSA-CAMELLIA128-SHA256", /* TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
284 "ECDH-RSA-CAMELLIA128-SHA256", /* TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
285 "PSK-CAMELLIA128-SHA256", /* TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
286 "DHE-PSK-CAMELLIA128-SHA256", /* TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
287 "RSA-PSK-CAMELLIA128-SHA256", /* TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
288 "ECDHE-PSK-CAMELLIA128-SHA256", /* TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 */
289 "CAMELLIA128-GCM-SHA256", /* TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 */
290 "DH-RSA-CAMELLIA128-GCM-SHA256", /* TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256 */
291 "DH-DSS-CAMELLIA128-GCM-SHA256", /* TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256 */
292 "ADH-CAMELLIA128-GCM-SHA256", /* TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256 */
293 "ECDH-ECDSA-CAMELLIA128-GCM-SHA256",/* TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 */
294 "ECDH-RSA-CAMELLIA128-GCM-SHA256", /* TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 */
295 "PSK-CAMELLIA128-GCM-SHA256", /* TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 */
296 "RSA-PSK-CAMELLIA128-GCM-SHA256", /* TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 */
297 "CAMELLIA128-SHA256", /* TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
298 "DH-DSS-CAMELLIA128-SHA256", /* TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 */
299 "DH-RSA-CAMELLIA128-SHA256", /* TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
300 "DHE-DSS-CAMELLIA128-SHA256", /* TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 */
301 "DHE-RSA-CAMELLIA128-SHA256", /* TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 */
302 "ADH-CAMELLIA128-SHA256", /* TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 */
304 /* blacklisted CAMELLIA256 encrpytion ciphers */
305 "CAMELLIA256-SHA", /* TLS_RSA_WITH_CAMELLIA_256_CBC_SHA */
306 "DH-RSA-CAMELLIA256-SHA", /* TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA */
307 "DH-DSS-CAMELLIA256-SHA", /* TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA */
308 "DHE-DSS-CAMELLIA256-SHA", /* TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA */
309 "DHE-RSA-CAMELLIA256-SHA", /* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA */
310 "ADH-CAMELLIA256-SHA", /* TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA */
311 "ECDHE-ECDSA-CAMELLIA256-SHA384", /* TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 */
312 "ECDH-ECDSA-CAMELLIA256-SHA384", /* TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 */
313 "ECDHE-RSA-CAMELLIA256-SHA384", /* TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 */
314 "ECDH-RSA-CAMELLIA256-SHA384", /* TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 */
315 "PSK-CAMELLIA256-SHA384", /* TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
316 "DHE-PSK-CAMELLIA256-SHA384", /* TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
317 "RSA-PSK-CAMELLIA256-SHA384", /* TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
318 "ECDHE-PSK-CAMELLIA256-SHA384", /* TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 */
319 "CAMELLIA256-SHA256", /* TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 */
320 "DH-DSS-CAMELLIA256-SHA256", /* TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 */
321 "DH-RSA-CAMELLIA256-SHA256", /* TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 */
322 "DHE-DSS-CAMELLIA256-SHA256", /* TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 */
323 "DHE-RSA-CAMELLIA256-SHA256", /* TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 */
324 "ADH-CAMELLIA256-SHA256", /* TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 */
325 "CAMELLIA256-GCM-SHA384", /* TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 */
326 "DH-RSA-CAMELLIA256-GCM-SHA384", /* TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384 */
327 "DH-DSS-CAMELLIA256-GCM-SHA384", /* TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 */
328 "ADH-CAMELLIA256-GCM-SHA384", /* TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384 */
329 "ECDH-ECDSA-CAMELLIA256-GCM-SHA384",/* TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 */
330 "ECDH-RSA-CAMELLIA256-GCM-SHA384", /* TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 */
331 "PSK-CAMELLIA256-GCM-SHA384", /* TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 */
332 "RSA-PSK-CAMELLIA256-GCM-SHA384", /* TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 */
334 /* The blacklisted ARIA encrpytion ciphers */
335 "ARIA128-SHA256", /* TLS_RSA_WITH_ARIA_128_CBC_SHA256 */
336 "ARIA256-SHA384", /* TLS_RSA_WITH_ARIA_256_CBC_SHA384 */
337 "DH-DSS-ARIA128-SHA256", /* TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256 */
338 "DH-DSS-ARIA256-SHA384", /* TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384 */
339 "DH-RSA-ARIA128-SHA256", /* TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256 */
340 "DH-RSA-ARIA256-SHA384", /* TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384 */
341 "DHE-DSS-ARIA128-SHA256", /* TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256 */
342 "DHE-DSS-ARIA256-SHA384", /* TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384 */
343 "DHE-RSA-ARIA128-SHA256", /* TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 */
344 "DHE-RSA-ARIA256-SHA384", /* TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 */
345 "ADH-ARIA128-SHA256", /* TLS_DH_anon_WITH_ARIA_128_CBC_SHA256 */
346 "ADH-ARIA256-SHA384", /* TLS_DH_anon_WITH_ARIA_256_CBC_SHA384 */
347 "ECDHE-ECDSA-ARIA128-SHA256", /* TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 */
348 "ECDHE-ECDSA-ARIA256-SHA384", /* TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 */
349 "ECDH-ECDSA-ARIA128-SHA256", /* TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 */
350 "ECDH-ECDSA-ARIA256-SHA384", /* TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 */
351 "ECDHE-RSA-ARIA128-SHA256", /* TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 */
352 "ECDHE-RSA-ARIA256-SHA384", /* TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 */
353 "ECDH-RSA-ARIA128-SHA256", /* TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 */
354 "ECDH-RSA-ARIA256-SHA384", /* TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 */
355 "ARIA128-GCM-SHA256", /* TLS_RSA_WITH_ARIA_128_GCM_SHA256 */
356 "ARIA256-GCM-SHA384", /* TLS_RSA_WITH_ARIA_256_GCM_SHA384 */
357 "DH-DSS-ARIA128-GCM-SHA256", /* TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256 */
358 "DH-DSS-ARIA256-GCM-SHA384", /* TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384 */
359 "DH-RSA-ARIA128-GCM-SHA256", /* TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256 */
360 "DH-RSA-ARIA256-GCM-SHA384", /* TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384 */
361 "ADH-ARIA128-GCM-SHA256", /* TLS_DH_anon_WITH_ARIA_128_GCM_SHA256 */
362 "ADH-ARIA256-GCM-SHA384", /* TLS_DH_anon_WITH_ARIA_256_GCM_SHA384 */
363 "ECDH-ECDSA-ARIA128-GCM-SHA256", /* TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 */
364 "ECDH-ECDSA-ARIA256-GCM-SHA384", /* TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 */
365 "ECDH-RSA-ARIA128-GCM-SHA256", /* TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 */
366 "ECDH-RSA-ARIA256-GCM-SHA384", /* TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 */
367 "PSK-ARIA128-SHA256", /* TLS_PSK_WITH_ARIA_128_CBC_SHA256 */
368 "PSK-ARIA256-SHA384", /* TLS_PSK_WITH_ARIA_256_CBC_SHA384 */
369 "DHE-PSK-ARIA128-SHA256", /* TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 */
370 "DHE-PSK-ARIA256-SHA384", /* TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 */
371 "RSA-PSK-ARIA128-SHA256", /* TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 */
372 "RSA-PSK-ARIA256-SHA384", /* TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 */
373 "ARIA128-GCM-SHA256", /* TLS_PSK_WITH_ARIA_128_GCM_SHA256 */
374 "ARIA256-GCM-SHA384", /* TLS_PSK_WITH_ARIA_256_GCM_SHA384 */
375 "RSA-PSK-ARIA128-GCM-SHA256", /* TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 */
376 "RSA-PSK-ARIA256-GCM-SHA384", /* TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 */
377 "ECDHE-PSK-ARIA128-SHA256", /* TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 */
378 "ECDHE-PSK-ARIA256-SHA384", /* TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 */
380 /* blacklisted SEED encryptions */
381 "SEED-SHA", /*TLS_RSA_WITH_SEED_CBC_SHA */
382 "DH-DSS-SEED-SHA", /* TLS_DH_DSS_WITH_SEED_CBC_SHA */
383 "DH-RSA-SEED-SHA", /* TLS_DH_RSA_WITH_SEED_CBC_SHA */
384 "DHE-DSS-SEED-SHA", /* TLS_DHE_DSS_WITH_SEED_CBC_SHA */
385 "DHE-RSA-SEED-SHA", /* TLS_DHE_RSA_WITH_SEED_CBC_SHA */
386 "ADH-SEED-SHA", /* TLS_DH_anon_WITH_SEED_CBC_SHA */
388 /* blacklisted KRB5 ciphers */
389 "KRB5-DES-CBC-SHA", /* TLS_KRB5_WITH_DES_CBC_SHA */
390 "KRB5-DES-CBC3-SHA", /* TLS_KRB5_WITH_3DES_EDE_CBC_SHA */
391 "KRB5-IDEA-CBC-SHA", /* TLS_KRB5_WITH_IDEA_CBC_SHA */
392 "KRB5-DES-CBC-MD5", /* TLS_KRB5_WITH_DES_CBC_MD5 */
393 "KRB5-DES-CBC3-MD5", /* TLS_KRB5_WITH_3DES_EDE_CBC_MD5 */
394 "KRB5-IDEA-CBC-MD5", /* TLS_KRB5_WITH_IDEA_CBC_MD5 */
395 "EXP-KRB5-DES-CBC-SHA", /* TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA */
396 "EXP-KRB5-DES-CBC-MD5", /* TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 */
397 "EXP-KRB5-RC2-CBC-SHA", /* TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA */
398 "EXP-KRB5-RC2-CBC-MD5", /* TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 */
400 /* blacklisted exoticas */
401 "DHE-DSS-CBC-SHA", /* TLS_DHE_DSS_WITH_DES_CBC_SHA */
402 "IDEA-CBC-SHA", /* TLS_RSA_WITH_IDEA_CBC_SHA */
404 /* not really sure if the following names are correct */
405 "SSL3_CK_SCSV", /* TLS_EMPTY_RENEGOTIATION_INFO_SCSV */
406 "SSL3_CK_FALLBACK_SCSV"
408 static size_t RFC7540_names_LEN = sizeof(RFC7540_names)/sizeof(RFC7540_names[0]);
411 static apr_hash_t *BLCNames;
413 static void cipher_init(apr_pool_t *pool)
415 apr_hash_t *hash = apr_hash_make(pool);
420 for (i = 0; i < RFC7540_names_LEN; ++i) {
421 apr_hash_set(hash, RFC7540_names[i], APR_HASH_KEY_STRING, source);
427 static int cipher_is_blacklisted(const char *cipher, const char **psource)
429 *psource = apr_hash_get(BLCNames, cipher, APR_HASH_KEY_STRING);
433 /*******************************************************************************
434 * Hooks for processing incoming connections:
435 * - pre_conn_before_tls switches SSL off for stream connections
436 * - process_conn take over connection in case of h2
438 static int h2_h2_process_conn(conn_rec* c);
439 static int h2_h2_remove_timeout(conn_rec* c);
440 static int h2_h2_post_read_req(request_rec *r);
443 /*******************************************************************************
444 * Once per lifetime init, retrieve optional functions
446 apr_status_t h2_h2_init(apr_pool_t *pool, server_rec *s)
449 ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, "h2_h2, child_init");
450 opt_ssl_engine_disable = APR_RETRIEVE_OPTIONAL_FN(ssl_engine_disable);
451 opt_ssl_is_https = APR_RETRIEVE_OPTIONAL_FN(ssl_is_https);
452 opt_ssl_var_lookup = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup);
454 if (!opt_ssl_is_https || !opt_ssl_var_lookup) {
455 ap_log_error(APLOG_MARK, APLOG_WARNING, 0, s,
456 APLOGNO(02951) "mod_ssl does not seem to be enabled");
464 int h2_h2_is_tls(conn_rec *c)
466 return opt_ssl_is_https && opt_ssl_is_https(c);
469 int h2_is_acceptable_connection(conn_rec *c, int require_all)
471 int is_tls = h2_h2_is_tls(c);
472 const h2_config *cfg = h2_config_get(c);
474 if (is_tls && h2_config_geti(cfg, H2_CONF_MODERN_TLS_ONLY) > 0) {
475 /* Check TLS connection for modern TLS parameters, as defined in
476 * RFC 7540 and https://wiki.mozilla.org/Security/Server_Side_TLS#Modern_compatibility
478 apr_pool_t *pool = c->pool;
479 server_rec *s = c->base_server;
482 if (!opt_ssl_var_lookup) {
483 /* unable to check */
487 /* Need Tlsv1.2 or higher, rfc 7540, ch. 9.2
489 val = opt_ssl_var_lookup(pool, s, c, NULL, (char*)"SSL_PROTOCOL");
491 if (strncmp("TLS", val, 3)
492 || !strcmp("TLSv1", val)
493 || !strcmp("TLSv1.1", val)) {
494 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
495 "h2_h2(%ld): tls protocol not suitable: %s",
500 else if (require_all) {
501 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
502 "h2_h2(%ld): tls protocol is indetermined", (long)c->id);
506 /* Check TLS cipher blacklist
508 val = opt_ssl_var_lookup(pool, s, c, NULL, (char*)"SSL_CIPHER");
511 if (cipher_is_blacklisted(val, &source)) {
512 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
513 "h2_h2(%ld): tls cipher %s blacklisted by %s",
514 (long)c->id, val, source);
518 else if (require_all) {
519 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, 0, c,
520 "h2_h2(%ld): tls cipher is indetermined", (long)c->id);
527 int h2_allows_h2_direct(conn_rec *c)
529 const h2_config *cfg = h2_config_get(c);
530 int h2_direct = h2_config_geti(cfg, H2_CONF_DIRECT);
533 if (h2_h2_is_tls(c)) {
534 /* disabled by default on TLS */
538 /* enabled if "Protocols h2c" is configured */
539 h2_direct = ap_is_allowed_protocol(c, NULL, NULL, "h2c");
545 int h2_allows_h2_upgrade(conn_rec *c)
547 const h2_config *cfg = h2_config_get(c);
548 int h2_upgrade = h2_config_geti(cfg, H2_CONF_UPGRADE);
550 return h2_upgrade > 0 || (h2_upgrade < 0 && !h2_h2_is_tls(c));
553 /*******************************************************************************
554 * Register various hooks
556 static const char *const mod_reqtimeout[] = { "reqtimeout.c", NULL};
557 static const char* const mod_ssl[] = {"mod_ssl.c", NULL};
559 void h2_h2_register_hooks(void)
561 /* When the connection processing actually starts, we might to
562 * take over, if h2* was selected as protocol.
564 ap_hook_process_connection(h2_h2_process_conn,
565 mod_ssl, NULL, APR_HOOK_MIDDLE);
567 /* Perform connection cleanup before the actual processing happens.
569 ap_hook_process_connection(h2_h2_remove_timeout,
570 mod_reqtimeout, NULL, APR_HOOK_LAST);
572 /* With "H2SerializeHeaders On", we install the filter in this hook
573 * that parses the response. This needs to happen before any other post
574 * read function terminates the request with an error. Otherwise we will
575 * never see the response.
577 ap_hook_post_read_request(h2_h2_post_read_req, NULL, NULL, APR_HOOK_REALLY_FIRST);
580 static int h2_h2_remove_timeout(conn_rec* c)
582 h2_ctx *ctx = h2_ctx_get(c);
584 if (h2_ctx_is_active(ctx) && !h2_ctx_is_task(ctx)) {
585 /* cleanup on master h2 connections */
586 ap_remove_input_filter_byhandle(c->input_filters, "reqtimeout");
592 int h2_h2_process_conn(conn_rec* c)
594 h2_ctx *ctx = h2_ctx_get(c);
596 ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "h2_h2, process_conn");
597 if (h2_ctx_is_task(ctx)) {
598 /* our stream pseudo connection */
602 if (h2_ctx_protocol_get(c)) {
603 /* Something has been negotiated */
605 else if (!strcmp(AP_PROTOCOL_HTTP1, ap_get_protocol(c))
606 && h2_allows_h2_direct(c)
607 && h2_is_acceptable_connection(c, 1)) {
608 /* connection still is on http/1.1 and H2Direct is enabled.
609 * Otherwise connection is in a fully acceptable state.
610 * -> peek at the first 24 incoming bytes
612 apr_bucket_brigade *temp;
617 temp = apr_brigade_create(c->pool, c->bucket_alloc);
618 status = ap_get_brigade(c->input_filters, temp,
619 AP_MODE_SPECULATIVE, APR_BLOCK_READ, 24);
621 if (status != APR_SUCCESS) {
622 ap_log_cerror(APLOG_MARK, APLOG_DEBUG, status, c,
623 "h2_h2, error reading 24 bytes speculative");
624 apr_brigade_destroy(temp);
628 apr_brigade_pflatten(temp, &s, &slen, c->pool);
629 if ((slen >= 24) && !memcmp(H2_MAGIC_TOKEN, s, 24)) {
630 ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
631 "h2_h2, direct mode detected");
632 h2_ctx_protocol_set(ctx, h2_h2_is_tls(c)? "h2" : "h2c");
635 ap_log_cerror(APLOG_MARK, APLOG_TRACE2, 0, c,
636 "h2_h2, not detected in %d bytes: %s",
640 apr_brigade_destroy(temp);
643 /* the connection is not HTTP/1.1 or not for us, don't touch it */
647 /* If "h2" was selected as protocol (by whatever mechanism), take over
650 if (h2_ctx_is_active(ctx)) {
651 ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c,
652 "h2_h2, connection, h2 active");
654 return h2_conn_process(c, NULL, ctx->server);
657 ap_log_cerror(APLOG_MARK, APLOG_TRACE1, 0, c, "h2_h2, declined");
661 static int h2_h2_post_read_req(request_rec *r)
663 h2_ctx *ctx = h2_ctx_rget(r);
664 struct h2_task *task = h2_ctx_get_task(ctx);
666 /* FIXME: sometimes, this hook gets called twice for a single request.
667 * This should not be, right? */
668 /* h2_task connection for a stream, not for h2c */
669 ap_log_rerror(APLOG_MARK, APLOG_TRACE3, 0, r,
670 "adding h1_to_h2_resp output filter");
671 if (task->serialize_headers) {
672 ap_remove_output_filter_byhandle(r->output_filters, "H1_TO_H2_RESP");
673 ap_add_output_filter("H1_TO_H2_RESP", task, r, r->connection);
676 /* replace the core http filter that formats response headers
677 * in HTTP/1 with our own that collects status and headers */
678 ap_remove_output_filter_byhandle(r->output_filters, "HTTP_HEADER");
679 ap_remove_output_filter_byhandle(r->output_filters, "H2_RESPONSE");
680 ap_add_output_filter("H2_RESPONSE", task, r, r->connection);
682 ap_add_output_filter("H2_TRAILERS", task, r, r->connection);