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
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 #include <assert.h>
17 #include <apr_lib.h>
18 #include <apr_strings.h>
19 
20 #include <httpd.h>
21 #include <http_connection.h>
22 #include <http_core.h>
23 #include <http_log.h>
24 
25 #include <rustls.h>
26 
27 #include "tls_proto.h"
28 #include "tls_conf.h"
29 #include "tls_util.h"
30 
31 extern module AP_MODULE_DECLARE_DATA tls_module;
32 APLOG_USE_MODULE(tls);
33 
34 
35 
36 /**
37  * Known cipher as registered in
38  * <https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml#tls-parameters-4>
39  */
40 static tls_cipher_t KNOWN_CIPHERS[] = {
41     { 0x0000, "TLS_NULL_WITH_NULL_NULL", NULL },
42     { 0x0001, "TLS_RSA_WITH_NULL_MD5", NULL },
43     { 0x0002, "TLS_RSA_WITH_NULL_SHA", NULL },
44     { 0x0003, "TLS_RSA_EXPORT_WITH_RC4_40_MD5", NULL },
45     { 0x0004, "TLS_RSA_WITH_RC4_128_MD5", NULL },
46     { 0x0005, "TLS_RSA_WITH_RC4_128_SHA", NULL },
47     { 0x0006, "TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5", NULL },
48     { 0x0007, "TLS_RSA_WITH_IDEA_CBC_SHA", NULL },
49     { 0x0008, "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA", NULL },
50     { 0x0009, "TLS_RSA_WITH_DES_CBC_SHA", NULL },
51     { 0x000a, "TLS_RSA_WITH_3DES_EDE_CBC_SHA", NULL },
52     { 0x000b, "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", NULL },
53     { 0x000c, "TLS_DH_DSS_WITH_DES_CBC_SHA", NULL },
54     { 0x000d, "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA", NULL },
55     { 0x000e, "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", NULL },
56     { 0x000f, "TLS_DH_RSA_WITH_DES_CBC_SHA", NULL },
57     { 0x0010, "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA", NULL },
58     { 0x0011, "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", NULL },
59     { 0x0012, "TLS_DHE_DSS_WITH_DES_CBC_SHA", NULL },
60     { 0x0013, "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA", NULL },
61     { 0x0014, "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", NULL },
62     { 0x0015, "TLS_DHE_RSA_WITH_DES_CBC_SHA", NULL },
63     { 0x0016, "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA", NULL },
64     { 0x0017, "TLS_DH_anon_EXPORT_WITH_RC4_40_MD5", NULL },
65     { 0x0018, "TLS_DH_anon_WITH_RC4_128_MD5", NULL },
66     { 0x0019, "TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA", NULL },
67     { 0x001a, "TLS_DH_anon_WITH_DES_CBC_SHA", NULL },
68     { 0x001b, "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA", NULL },
69     { 0x001c, "SSL_FORTEZZA_KEA_WITH_NULL_SHA", NULL },
70     { 0x001d, "SSL_FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA", NULL },
71     { 0x001e, "TLS_KRB5_WITH_DES_CBC_SHA_or_SSL_FORTEZZA_KEA_WITH_RC4_128_SHA", NULL },
72     { 0x001f, "TLS_KRB5_WITH_3DES_EDE_CBC_SHA", NULL },
73     { 0x0020, "TLS_KRB5_WITH_RC4_128_SHA", NULL },
74     { 0x0021, "TLS_KRB5_WITH_IDEA_CBC_SHA", NULL },
75     { 0x0022, "TLS_KRB5_WITH_DES_CBC_MD5", NULL },
76     { 0x0023, "TLS_KRB5_WITH_3DES_EDE_CBC_MD5", NULL },
77     { 0x0024, "TLS_KRB5_WITH_RC4_128_MD5", NULL },
78     { 0x0025, "TLS_KRB5_WITH_IDEA_CBC_MD5", NULL },
79     { 0x0026, "TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA", NULL },
80     { 0x0027, "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA", NULL },
81     { 0x0028, "TLS_KRB5_EXPORT_WITH_RC4_40_SHA", NULL },
82     { 0x0029, "TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5", NULL },
83     { 0x002a, "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5", NULL },
84     { 0x002b, "TLS_KRB5_EXPORT_WITH_RC4_40_MD5", NULL },
85     { 0x002c, "TLS_PSK_WITH_NULL_SHA", NULL },
86     { 0x002d, "TLS_DHE_PSK_WITH_NULL_SHA", NULL },
87     { 0x002e, "TLS_RSA_PSK_WITH_NULL_SHA", NULL },
88     { 0x002f, "TLS_RSA_WITH_AES_128_CBC_SHA", NULL },
89     { 0x0030, "TLS_DH_DSS_WITH_AES_128_CBC_SHA", NULL },
90     { 0x0031, "TLS_DH_RSA_WITH_AES_128_CBC_SHA", NULL },
91     { 0x0032, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", NULL },
92     { 0x0033, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", NULL },
93     { 0x0034, "TLS_DH_anon_WITH_AES_128_CBC_SHA", NULL },
94     { 0x0035, "TLS_RSA_WITH_AES_256_CBC_SHA", NULL },
95     { 0x0036, "TLS_DH_DSS_WITH_AES_256_CBC_SHA", NULL },
96     { 0x0037, "TLS_DH_RSA_WITH_AES_256_CBC_SHA", NULL },
97     { 0x0038, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA", NULL },
98     { 0x0039, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", NULL },
99     { 0x003a, "TLS_DH_anon_WITH_AES_256_CBC_SHA", NULL },
100     { 0x003b, "TLS_RSA_WITH_NULL_SHA256", "NULL-SHA256" },
101     { 0x003c, "TLS_RSA_WITH_AES_128_CBC_SHA256", "AES128-SHA256" },
102     { 0x003d, "TLS_RSA_WITH_AES_256_CBC_SHA256", "AES256-SHA256" },
103     { 0x003e, "TLS_DH_DSS_WITH_AES_128_CBC_SHA256", "DH-DSS-AES128-SHA256" },
104     { 0x003f, "TLS_DH_RSA_WITH_AES_128_CBC_SHA256", "DH-RSA-AES128-SHA256" },
105     { 0x0040, "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", "DHE-DSS-AES128-SHA256" },
106     { 0x0041, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA", NULL },
107     { 0x0042, "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA", NULL },
108     { 0x0043, "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA", NULL },
109     { 0x0044, "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA", NULL },
110     { 0x0045, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA", NULL },
111     { 0x0046, "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA", NULL },
112     { 0x0047, "TLS_ECDH_ECDSA_WITH_NULL_SHA_draft", NULL },
113     { 0x0048, "TLS_ECDH_ECDSA_WITH_RC4_128_SHA_draft", NULL },
114     { 0x0049, "TLS_ECDH_ECDSA_WITH_DES_CBC_SHA_draft", NULL },
115     { 0x004a, "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA_draft", NULL },
116     { 0x004b, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA_draft", NULL },
117     { 0x004c, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA_draft", NULL },
118     { 0x004d, "TLS_ECDH_ECNRA_WITH_DES_CBC_SHA_draft", NULL },
119     { 0x004e, "TLS_ECDH_ECNRA_WITH_3DES_EDE_CBC_SHA_draft", NULL },
120     { 0x004f, "TLS_ECMQV_ECDSA_NULL_SHA_draft", NULL },
121     { 0x0050, "TLS_ECMQV_ECDSA_WITH_RC4_128_SHA_draft", NULL },
122     { 0x0051, "TLS_ECMQV_ECDSA_WITH_DES_CBC_SHA_draft", NULL },
123     { 0x0052, "TLS_ECMQV_ECDSA_WITH_3DES_EDE_CBC_SHA_draft", NULL },
124     { 0x0053, "TLS_ECMQV_ECNRA_NULL_SHA_draft", NULL },
125     { 0x0054, "TLS_ECMQV_ECNRA_WITH_RC4_128_SHA_draft", NULL },
126     { 0x0055, "TLS_ECMQV_ECNRA_WITH_DES_CBC_SHA_draft", NULL },
127     { 0x0056, "TLS_ECMQV_ECNRA_WITH_3DES_EDE_CBC_SHA_draft", NULL },
128     { 0x0057, "TLS_ECDH_anon_NULL_WITH_SHA_draft", NULL },
129     { 0x0058, "TLS_ECDH_anon_WITH_RC4_128_SHA_draft", NULL },
130     { 0x0059, "TLS_ECDH_anon_WITH_DES_CBC_SHA_draft", NULL },
131     { 0x005a, "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA_draft", NULL },
132     { 0x005b, "TLS_ECDH_anon_EXPORT_WITH_DES40_CBC_SHA_draft", NULL },
133     { 0x005c, "TLS_ECDH_anon_EXPORT_WITH_RC4_40_SHA_draft", NULL },
134     { 0x0060, "TLS_RSA_EXPORT1024_WITH_RC4_56_MD5", NULL },
135     { 0x0061, "TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5", NULL },
136     { 0x0062, "TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA", NULL },
137     { 0x0063, "TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA", NULL },
138     { 0x0064, "TLS_RSA_EXPORT1024_WITH_RC4_56_SHA", NULL },
139     { 0x0065, "TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA", NULL },
140     { 0x0066, "TLS_DHE_DSS_WITH_RC4_128_SHA", NULL },
141     { 0x0067, "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", "DHE-RSA-AES128-SHA256" },
142     { 0x0068, "TLS_DH_DSS_WITH_AES_256_CBC_SHA256", "DH-DSS-AES256-SHA256" },
143     { 0x0069, "TLS_DH_RSA_WITH_AES_256_CBC_SHA256", "DH-RSA-AES256-SHA256" },
144     { 0x006a, "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", "DHE-DSS-AES256-SHA256" },
145     { 0x006b, "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", "DHE-RSA-AES256-SHA256" },
146     { 0x006c, "TLS_DH_anon_WITH_AES_128_CBC_SHA256", "ADH-AES128-SHA256" },
147     { 0x006d, "TLS_DH_anon_WITH_AES_256_CBC_SHA256", "ADH-AES256-SHA256" },
148     { 0x0072, "TLS_DHE_DSS_WITH_3DES_EDE_CBC_RMD", NULL },
149     { 0x0073, "TLS_DHE_DSS_WITH_AES_128_CBC_RMD", NULL },
150     { 0x0074, "TLS_DHE_DSS_WITH_AES_256_CBC_RMD", NULL },
151     { 0x0077, "TLS_DHE_RSA_WITH_3DES_EDE_CBC_RMD", NULL },
152     { 0x0078, "TLS_DHE_RSA_WITH_AES_128_CBC_RMD", NULL },
153     { 0x0079, "TLS_DHE_RSA_WITH_AES_256_CBC_RMD", NULL },
154     { 0x007c, "TLS_RSA_WITH_3DES_EDE_CBC_RMD", NULL },
155     { 0x007d, "TLS_RSA_WITH_AES_128_CBC_RMD", NULL },
156     { 0x007e, "TLS_RSA_WITH_AES_256_CBC_RMD", NULL },
157     { 0x0080, "TLS_GOSTR341094_WITH_28147_CNT_IMIT", NULL },
158     { 0x0081, "TLS_GOSTR341001_WITH_28147_CNT_IMIT", NULL },
159     { 0x0082, "TLS_GOSTR341094_WITH_NULL_GOSTR3411", NULL },
160     { 0x0083, "TLS_GOSTR341001_WITH_NULL_GOSTR3411", NULL },
161     { 0x0084, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA", NULL },
162     { 0x0085, "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA", NULL },
163     { 0x0086, "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA", NULL },
164     { 0x0087, "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA", NULL },
165     { 0x0088, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA", NULL },
166     { 0x0089, "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA", NULL },
167     { 0x008a, "TLS_PSK_WITH_RC4_128_SHA", "PSK-RC4-SHA" },
168     { 0x008b, "TLS_PSK_WITH_3DES_EDE_CBC_SHA", "PSK-3DES-EDE-CBC-SHA" },
169     { 0x008c, "TLS_PSK_WITH_AES_128_CBC_SHA", NULL },
170     { 0x008d, "TLS_PSK_WITH_AES_256_CBC_SHA", NULL },
171     { 0x008e, "TLS_DHE_PSK_WITH_RC4_128_SHA", NULL },
172     { 0x008f, "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA", NULL },
173     { 0x0090, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA", NULL },
174     { 0x0091, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA", NULL },
175     { 0x0092, "TLS_RSA_PSK_WITH_RC4_128_SHA", NULL },
176     { 0x0093, "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA", NULL },
177     { 0x0094, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA", NULL },
178     { 0x0095, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA", NULL },
179     { 0x0096, "TLS_RSA_WITH_SEED_CBC_SHA", NULL },
180     { 0x0097, "TLS_DH_DSS_WITH_SEED_CBC_SHA", NULL },
181     { 0x0098, "TLS_DH_RSA_WITH_SEED_CBC_SHA", NULL },
182     { 0x0099, "TLS_DHE_DSS_WITH_SEED_CBC_SHA", NULL },
183     { 0x009a, "TLS_DHE_RSA_WITH_SEED_CBC_SHA", NULL },
184     { 0x009b, "TLS_DH_anon_WITH_SEED_CBC_SHA", NULL },
185     { 0x009c, "TLS_RSA_WITH_AES_128_GCM_SHA256", "AES128-GCM-SHA256" },
186     { 0x009d, "TLS_RSA_WITH_AES_256_GCM_SHA384", "AES256-GCM-SHA384" },
187     { 0x009e, "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", "DHE-RSA-AES128-GCM-SHA256" },
188     { 0x009f, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", "DHE-RSA-AES256-GCM-SHA384" },
189     { 0x00a0, "TLS_DH_RSA_WITH_AES_128_GCM_SHA256", "DH-RSA-AES128-GCM-SHA256" },
190     { 0x00a1, "TLS_DH_RSA_WITH_AES_256_GCM_SHA384", "DH-RSA-AES256-GCM-SHA384" },
191     { 0x00a2, "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256", "DHE-DSS-AES128-GCM-SHA256" },
192     { 0x00a3, "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384", "DHE-DSS-AES256-GCM-SHA384" },
193     { 0x00a4, "TLS_DH_DSS_WITH_AES_128_GCM_SHA256", "DH-DSS-AES128-GCM-SHA256" },
194     { 0x00a5, "TLS_DH_DSS_WITH_AES_256_GCM_SHA384", "DH-DSS-AES256-GCM-SHA384" },
195     { 0x00a6, "TLS_DH_anon_WITH_AES_128_GCM_SHA256", "ADH-AES128-GCM-SHA256" },
196     { 0x00a7, "TLS_DH_anon_WITH_AES_256_GCM_SHA384", "ADH-AES256-GCM-SHA384" },
197     { 0x00a8, "TLS_PSK_WITH_AES_128_GCM_SHA256", NULL },
198     { 0x00a9, "TLS_PSK_WITH_AES_256_GCM_SHA384", NULL },
199     { 0x00aa, "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256", NULL },
200     { 0x00ab, "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384", NULL },
201     { 0x00ac, "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256", NULL },
202     { 0x00ad, "TLS_RSA_PSK_WITH_AES_256_GCM_SHA384", NULL },
203     { 0x00ae, "TLS_PSK_WITH_AES_128_CBC_SHA256", "PSK-AES128-CBC-SHA" },
204     { 0x00af, "TLS_PSK_WITH_AES_256_CBC_SHA384", "PSK-AES256-CBC-SHA" },
205     { 0x00b0, "TLS_PSK_WITH_NULL_SHA256", NULL },
206     { 0x00b1, "TLS_PSK_WITH_NULL_SHA384", NULL },
207     { 0x00b2, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256", NULL },
208     { 0x00b3, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384", NULL },
209     { 0x00b4, "TLS_DHE_PSK_WITH_NULL_SHA256", NULL },
210     { 0x00b5, "TLS_DHE_PSK_WITH_NULL_SHA384", NULL },
211     { 0x00b6, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256", NULL },
212     { 0x00b7, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384", NULL },
213     { 0x00b8, "TLS_RSA_PSK_WITH_NULL_SHA256", NULL },
214     { 0x00b9, "TLS_RSA_PSK_WITH_NULL_SHA384", NULL },
215     { 0x00ba, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256", NULL },
216     { 0x00bb, "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256", NULL },
217     { 0x00bc, "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256", NULL },
218     { 0x00bd, "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256", NULL },
219     { 0x00be, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", NULL },
220     { 0x00bf, "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256", NULL },
221     { 0x00c0, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256", NULL },
222     { 0x00c1, "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256", NULL },
223     { 0x00c2, "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256", NULL },
224     { 0x00c3, "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256", NULL },
225     { 0x00c4, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256", NULL },
226     { 0x00c5, "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256", NULL },
227     { 0x00ff, "TLS_EMPTY_RENEGOTIATION_INFO_SCSV", NULL },
228     { 0x1301, "TLS_AES_128_GCM_SHA256", "TLS13_AES_128_GCM_SHA256" },
229     { 0x1302, "TLS_AES_256_GCM_SHA384", "TLS13_AES_256_GCM_SHA384" },
230     { 0x1303, "TLS_CHACHA20_POLY1305_SHA256", "TLS13_CHACHA20_POLY1305_SHA256" },
231     { 0x1304, "TLS_AES_128_CCM_SHA256", "TLS13_AES_128_CCM_SHA256" },
232     { 0x1305, "TLS_AES_128_CCM_8_SHA256", "TLS13_AES_128_CCM_8_SHA256" },
233     { 0xc001, "TLS_ECDH_ECDSA_WITH_NULL_SHA", NULL },
234     { 0xc002, "TLS_ECDH_ECDSA_WITH_RC4_128_SHA", NULL },
235     { 0xc003, "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA", NULL },
236     { 0xc004, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", NULL },
237     { 0xc005, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", NULL },
238     { 0xc006, "TLS_ECDHE_ECDSA_WITH_NULL_SHA", NULL },
239     { 0xc007, "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", NULL },
240     { 0xc008, "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", NULL },
241     { 0xc009, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", NULL },
242     { 0xc00a, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", NULL },
243     { 0xc00b, "TLS_ECDH_RSA_WITH_NULL_SHA", NULL },
244     { 0xc00c, "TLS_ECDH_RSA_WITH_RC4_128_SHA", NULL },
245     { 0xc00d, "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA", NULL },
246     { 0xc00e, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", NULL },
247     { 0xc00f, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", NULL },
248     { 0xc010, "TLS_ECDHE_RSA_WITH_NULL_SHA", NULL },
249     { 0xc011, "TLS_ECDHE_RSA_WITH_RC4_128_SHA", NULL },
250     { 0xc012, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", NULL },
251     { 0xc013, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", NULL },
252     { 0xc014, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", NULL },
253     { 0xc015, "TLS_ECDH_anon_WITH_NULL_SHA", NULL },
254     { 0xc016, "TLS_ECDH_anon_WITH_RC4_128_SHA", NULL },
255     { 0xc017, "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA", NULL },
256     { 0xc018, "TLS_ECDH_anon_WITH_AES_128_CBC_SHA", NULL },
257     { 0xc019, "TLS_ECDH_anon_WITH_AES_256_CBC_SHA", NULL },
258     { 0xc01a, "TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA", NULL },
259     { 0xc01b, "TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA", NULL },
260     { 0xc01c, "TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA", NULL },
261     { 0xc01d, "TLS_SRP_SHA_WITH_AES_128_CBC_SHA", NULL },
262     { 0xc01e, "TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA", NULL },
263     { 0xc01f, "TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA", NULL },
264     { 0xc020, "TLS_SRP_SHA_WITH_AES_256_CBC_SHA", NULL },
265     { 0xc021, "TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA", NULL },
266     { 0xc022, "TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA", NULL },
267     { 0xc023, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", "ECDHE-ECDSA-AES128-SHA256" },
268     { 0xc024, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", "ECDHE-ECDSA-AES256-SHA384" },
269     { 0xc025, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", "ECDH-ECDSA-AES128-SHA256" },
270     { 0xc026, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", "ECDH-ECDSA-AES256-SHA384" },
271     { 0xc027, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "ECDHE-RSA-AES128-SHA256" },
272     { 0xc028, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", "ECDHE-RSA-AES256-SHA384" },
273     { 0xc029, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", "ECDH-RSA-AES128-SHA256" },
274     { 0xc02a, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", "ECDH-RSA-AES256-SHA384" },
275     { 0xc02b, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "ECDHE-ECDSA-AES128-GCM-SHA256" },
276     { 0xc02c, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "ECDHE-ECDSA-AES256-GCM-SHA384" },
277     { 0xc02d, "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", "ECDH-ECDSA-AES128-GCM-SHA256" },
278     { 0xc02e, "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384", "ECDH-ECDSA-AES256-GCM-SHA384" },
279     { 0xc02f, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "ECDHE-RSA-AES128-GCM-SHA256" },
280     { 0xc030, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "ECDHE-RSA-AES256-GCM-SHA384" },
281     { 0xc031, "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", "ECDH-RSA-AES128-GCM-SHA256" },
282     { 0xc032, "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384", "ECDH-RSA-AES256-GCM-SHA384" },
283     { 0xc033, "TLS_ECDHE_PSK_WITH_RC4_128_SHA", NULL },
284     { 0xc034, "TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA", NULL },
285     { 0xc035, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA", NULL },
286     { 0xc036, "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA", NULL },
287     { 0xc037, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256", NULL },
288     { 0xc038, "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384", NULL },
289     { 0xc039, "TLS_ECDHE_PSK_WITH_NULL_SHA", NULL },
290     { 0xc03a, "TLS_ECDHE_PSK_WITH_NULL_SHA256", NULL },
291     { 0xc03b, "TLS_ECDHE_PSK_WITH_NULL_SHA384", NULL },
292     { 0xc03c, "TLS_RSA_WITH_ARIA_128_CBC_SHA256", NULL },
293     { 0xc03d, "TLS_RSA_WITH_ARIA_256_CBC_SHA384", NULL },
294     { 0xc03e, "TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256", NULL },
295     { 0xc03f, "TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384", NULL },
296     { 0xc040, "TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256", NULL },
297     { 0xc041, "TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384", NULL },
298     { 0xc042, "TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256", NULL },
299     { 0xc043, "TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384", NULL },
300     { 0xc044, "TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256", NULL },
301     { 0xc045, "TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384", NULL },
302     { 0xc046, "TLS_DH_anon_WITH_ARIA_128_CBC_SHA256", NULL },
303     { 0xc047, "TLS_DH_anon_WITH_ARIA_256_CBC_SHA384", NULL },
304     { 0xc048, "TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256", NULL },
305     { 0xc049, "TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384", NULL },
306     { 0xc04a, "TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256", NULL },
307     { 0xc04b, "TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384", NULL },
308     { 0xc04c, "TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256", NULL },
309     { 0xc04d, "TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384", NULL },
310     { 0xc04e, "TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256", NULL },
311     { 0xc04f, "TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384", NULL },
312     { 0xc050, "TLS_RSA_WITH_ARIA_128_GCM_SHA256", NULL },
313     { 0xc051, "TLS_RSA_WITH_ARIA_256_GCM_SHA384", NULL },
314     { 0xc052, "TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256", NULL },
315     { 0xc053, "TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384", NULL },
316     { 0xc054, "TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256", NULL },
317     { 0xc055, "TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384", NULL },
318     { 0xc056, "TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256", NULL },
319     { 0xc057, "TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384", NULL },
320     { 0xc058, "TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256", NULL },
321     { 0xc059, "TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384", NULL },
322     { 0xc05a, "TLS_DH_anon_WITH_ARIA_128_GCM_SHA256", NULL },
323     { 0xc05b, "TLS_DH_anon_WITH_ARIA_256_GCM_SHA384", NULL },
324     { 0xc05c, "TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256", NULL },
325     { 0xc05d, "TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384", NULL },
326     { 0xc05e, "TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256", NULL },
327     { 0xc05f, "TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384", NULL },
328     { 0xc060, "TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256", NULL },
329     { 0xc061, "TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384", NULL },
330     { 0xc062, "TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256", NULL },
331     { 0xc063, "TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384", NULL },
332     { 0xc064, "TLS_PSK_WITH_ARIA_128_CBC_SHA256", NULL },
333     { 0xc065, "TLS_PSK_WITH_ARIA_256_CBC_SHA384", NULL },
334     { 0xc066, "TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256", NULL },
335     { 0xc067, "TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384", NULL },
336     { 0xc068, "TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256", NULL },
337     { 0xc069, "TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384", NULL },
338     { 0xc06a, "TLS_PSK_WITH_ARIA_128_GCM_SHA256", NULL },
339     { 0xc06b, "TLS_PSK_WITH_ARIA_256_GCM_SHA384", NULL },
340     { 0xc06c, "TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256", NULL },
341     { 0xc06d, "TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384", NULL },
342     { 0xc06e, "TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256", NULL },
343     { 0xc06f, "TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384", NULL },
344     { 0xc070, "TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256", NULL },
345     { 0xc071, "TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384", NULL },
346     { 0xc072, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256", NULL },
347     { 0xc073, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384", NULL },
348     { 0xc074, "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256", NULL },
349     { 0xc075, "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384", NULL },
350     { 0xc076, "TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", NULL },
351     { 0xc077, "TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384", NULL },
352     { 0xc078, "TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256", NULL },
353     { 0xc079, "TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384", NULL },
354     { 0xc07a, "TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256", NULL },
355     { 0xc07b, "TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384", NULL },
356     { 0xc07c, "TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256", NULL },
357     { 0xc07d, "TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384", NULL },
358     { 0xc07e, "TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256", NULL },
359     { 0xc07f, "TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384", NULL },
360     { 0xc080, "TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256", NULL },
361     { 0xc081, "TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384", NULL },
362     { 0xc082, "TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256", NULL },
363     { 0xc083, "TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384", NULL },
364     { 0xc084, "TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256", NULL },
365     { 0xc085, "TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384", NULL },
366     { 0xc086, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256", NULL },
367     { 0xc087, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384", NULL },
368     { 0xc088, "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256", NULL },
369     { 0xc089, "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384", NULL },
370     { 0xc08a, "TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256", NULL },
371     { 0xc08b, "TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384", NULL },
372     { 0xc08c, "TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256", NULL },
373     { 0xc08d, "TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384", NULL },
374     { 0xc08e, "TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256", NULL },
375     { 0xc08f, "TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384", NULL },
376     { 0xc090, "TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256", NULL },
377     { 0xc091, "TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384", NULL },
378     { 0xc092, "TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256", NULL },
379     { 0xc093, "TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384", NULL },
380     { 0xc094, "TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256", NULL },
381     { 0xc095, "TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384", NULL },
382     { 0xc096, "TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", NULL },
383     { 0xc097, "TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", NULL },
384     { 0xc098, "TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256", NULL },
385     { 0xc099, "TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384", NULL },
386     { 0xc09a, "TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256", NULL },
387     { 0xc09b, "TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384", NULL },
388     { 0xc09c, "TLS_RSA_WITH_AES_128_CCM", NULL },
389     { 0xc09d, "TLS_RSA_WITH_AES_256_CCM", NULL },
390     { 0xc09e, "TLS_DHE_RSA_WITH_AES_128_CCM", NULL },
391     { 0xc09f, "TLS_DHE_RSA_WITH_AES_256_CCM", NULL },
392     { 0xc0a0, "TLS_RSA_WITH_AES_128_CCM_8", NULL },
393     { 0xc0a1, "TLS_RSA_WITH_AES_256_CCM_8", NULL },
394     { 0xc0a2, "TLS_DHE_RSA_WITH_AES_128_CCM_8", NULL },
395     { 0xc0a3, "TLS_DHE_RSA_WITH_AES_256_CCM_8", NULL },
396     { 0xc0a4, "TLS_PSK_WITH_AES_128_CCM", NULL },
397     { 0xc0a5, "TLS_PSK_WITH_AES_256_CCM", NULL },
398     { 0xc0a6, "TLS_DHE_PSK_WITH_AES_128_CCM", NULL },
399     { 0xc0a7, "TLS_DHE_PSK_WITH_AES_256_CCM", NULL },
400     { 0xc0a8, "TLS_PSK_WITH_AES_128_CCM_8", NULL },
401     { 0xc0a9, "TLS_PSK_WITH_AES_256_CCM_8", NULL },
402     { 0xc0aa, "TLS_PSK_DHE_WITH_AES_128_CCM_8", NULL },
403     { 0xc0ab, "TLS_PSK_DHE_WITH_AES_256_CCM_8", NULL },
404     { 0xcca8, "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", "ECDHE-RSA-CHACHA20-POLY1305" },
405     { 0xcca9, "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", "ECDHE-ECDSA-CHACHA20-POLY1305" },
406     { 0xccaa, "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256", "DHE-RSA-CHACHA20-POLY1305" },
407     { 0xccab, "TLS_PSK_WITH_CHACHA20_POLY1305_SHA256", "PSK-CHACHA20-POLY1305" },
408     { 0xccac, "TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256", "ECDHE-PSK-CHACHA20-POLY1305" },
409     { 0xccad, "TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256", "DHE-PSK-CHACHA20-POLY1305" },
410     { 0xccae, "TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256", "RSA-PSK-CHACHA20-POLY1305" },
411     { 0xfefe, "SSL_RSA_FIPS_WITH_DES_CBC_SHA", NULL },
412     { 0xfeff, "SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA", NULL },
413 };
414 
415 typedef struct {
416     apr_uint16_t id;
417     const rustls_supported_ciphersuite *rustls_suite;
418 } rustls_cipher_t;
419 
tls_proto_init(apr_pool_t * pool,server_rec * s)420 tls_proto_conf_t *tls_proto_init(apr_pool_t *pool, server_rec *s)
421 {
422     tls_proto_conf_t *conf;
423     tls_cipher_t *cipher;
424     const rustls_supported_ciphersuite *rustls_suite;
425     rustls_cipher_t *rcipher;
426     apr_uint16_t id;
427     apr_size_t i;
428 
429     (void)s;
430     conf = apr_pcalloc(pool, sizeof(*conf));
431 
432     conf->supported_versions = apr_array_make(pool, 3, sizeof(apr_uint16_t));
433     /* Until we can look that up at crustls, we assume what we currently know */
434     APR_ARRAY_PUSH(conf->supported_versions, apr_uint16_t) = TLS_VERSION_1_2;
435     APR_ARRAY_PUSH(conf->supported_versions, apr_uint16_t) = TLS_VERSION_1_3;
436 
437     conf->known_ciphers_by_name = apr_hash_make(pool);
438     conf->known_ciphers_by_id = apr_hash_make(pool);
439     for (i = 0; i < TLS_DIM(KNOWN_CIPHERS); ++i) {
440         cipher = &KNOWN_CIPHERS[i];
441         apr_hash_set(conf->known_ciphers_by_id, &cipher->id, sizeof(apr_uint16_t), cipher);
442         apr_hash_set(conf->known_ciphers_by_name, cipher->name, APR_HASH_KEY_STRING, cipher);
443         if (cipher->alias) {
444             apr_hash_set(conf->known_ciphers_by_name, cipher->alias, APR_HASH_KEY_STRING, cipher);
445         }
446     }
447 
448     conf->supported_cipher_ids = apr_array_make(pool, 10, sizeof(apr_uint16_t));
449     conf->rustls_ciphers_by_id = apr_hash_make(pool);
450     i = 0;
451     while ((rustls_suite = rustls_all_ciphersuites_get_entry(i++))) {
452         id = rustls_supported_ciphersuite_get_suite(rustls_suite);
453         rcipher = apr_pcalloc(pool, sizeof(*rcipher));
454         rcipher->id = id;
455         rcipher->rustls_suite = rustls_suite;
456         APR_ARRAY_PUSH(conf->supported_cipher_ids, apr_uint16_t) = id;
457         apr_hash_set(conf->rustls_ciphers_by_id, &rcipher->id, sizeof(apr_uint16_t), rcipher);
458 
459     }
460 
461     return conf;
462 }
463 
tls_proto_get_cipher_names(tls_proto_conf_t * conf,const apr_array_header_t * ciphers,apr_pool_t * pool)464 const char *tls_proto_get_cipher_names(
465     tls_proto_conf_t *conf, const apr_array_header_t *ciphers, apr_pool_t *pool)
466 {
467     apr_array_header_t *names;
468     int n;
469 
470     names = apr_array_make(pool, ciphers->nelts, sizeof(const char*));
471     for (n = 0; n < ciphers->nelts; ++n) {
472         apr_uint16_t id = APR_ARRAY_IDX(ciphers, n, apr_uint16_t);
473         APR_ARRAY_PUSH(names, const char *) = tls_proto_get_cipher_name(conf, id, pool);
474     }
475     return apr_array_pstrcat(pool, names, ':');
476 }
477 
tls_proto_pre_config(apr_pool_t * pool,apr_pool_t * ptemp)478 apr_status_t tls_proto_pre_config(apr_pool_t *pool, apr_pool_t *ptemp)
479 {
480     (void)pool;
481     (void)ptemp;
482     return APR_SUCCESS;
483 }
484 
tls_proto_post_config(apr_pool_t * pool,apr_pool_t * ptemp,server_rec * s)485 apr_status_t tls_proto_post_config(apr_pool_t *pool, apr_pool_t *ptemp, server_rec *s)
486 {
487     tls_conf_server_t *sc = tls_conf_server_get(s);
488     tls_proto_conf_t *conf = sc->global->proto;
489 
490     (void)pool;
491     if (APLOGdebug(s)) {
492         ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(10314)
493                      "tls ciphers supported: %s",
494                      tls_proto_get_cipher_names(conf, conf->supported_cipher_ids, ptemp));
495     }
496     return APR_SUCCESS;
497 }
498 
get_uint16_from(const char * name,const char * prefix,apr_uint16_t * pint)499 static apr_status_t get_uint16_from(const char *name, const char *prefix, apr_uint16_t *pint)
500 {
501     apr_size_t plen = strlen(prefix);
502     if (strlen(name) == plen+4 && !strncmp(name, prefix, plen)) {
503         /* may be a hex notation cipher id */
504         char *end = NULL;
505         apr_int64_t code = apr_strtoi64(name + plen, &end, 16);
506         if ((!end || !*end) && code && code <= APR_UINT16_MAX) {
507             *pint = (apr_uint16_t)code;
508             return APR_SUCCESS;
509         }
510     }
511     return APR_ENOENT;
512 }
513 
tls_proto_get_version_by_name(tls_proto_conf_t * conf,const char * name)514 apr_uint16_t tls_proto_get_version_by_name(tls_proto_conf_t *conf, const char *name)
515 {
516     apr_uint16_t version;
517     (void)conf;
518     if (!apr_strnatcasecmp(name, "TLSv1.2")) {
519         return TLS_VERSION_1_2;
520     }
521     else if (!apr_strnatcasecmp(name, "TLSv1.3")) {
522         return TLS_VERSION_1_3;
523     }
524     if (APR_SUCCESS == get_uint16_from(name, "TLSv0x", &version)) {
525         return version;
526     }
527     return 0;
528 }
529 
tls_proto_get_version_name(tls_proto_conf_t * conf,apr_uint16_t id,apr_pool_t * pool)530 const char *tls_proto_get_version_name(
531     tls_proto_conf_t *conf, apr_uint16_t id, apr_pool_t *pool)
532 {
533     (void)conf;
534     switch (id) {
535     case TLS_VERSION_1_2:
536         return "TLSv1.2";
537     case TLS_VERSION_1_3:
538         return "TLSv1.3";
539     default:
540         return apr_psprintf(pool, "TLSv0x%04x", id);
541     }
542 }
543 
tls_proto_create_versions_plus(tls_proto_conf_t * conf,apr_uint16_t min_version,apr_pool_t * pool)544 apr_array_header_t *tls_proto_create_versions_plus(
545     tls_proto_conf_t *conf, apr_uint16_t min_version, apr_pool_t *pool)
546 {
547     apr_array_header_t *versions = apr_array_make(pool, 3, sizeof(apr_uint16_t));
548     apr_uint16_t version;
549     int i;
550 
551     for (i = 0; i < conf->supported_versions->nelts; ++i) {
552         version = APR_ARRAY_IDX(conf->supported_versions, i, apr_uint16_t);
553         if (version >= min_version) {
554             APR_ARRAY_PUSH(versions, apr_uint16_t) = version;
555         }
556     }
557     return versions;
558 }
559 
tls_proto_is_cipher_supported(tls_proto_conf_t * conf,apr_uint16_t cipher)560 int tls_proto_is_cipher_supported(tls_proto_conf_t *conf, apr_uint16_t cipher)
561 {
562     return tls_util_array_uint16_contains(conf->supported_cipher_ids, cipher);
563 }
564 
tls_proto_get_cipher_by_name(tls_proto_conf_t * conf,const char * name,apr_uint16_t * pcipher)565 apr_status_t tls_proto_get_cipher_by_name(
566     tls_proto_conf_t *conf, const char *name, apr_uint16_t *pcipher)
567 {
568     tls_cipher_t *cipher = apr_hash_get(conf->known_ciphers_by_name, name, APR_HASH_KEY_STRING);
569     if (cipher) {
570         *pcipher = cipher->id;
571         return APR_SUCCESS;
572     }
573     return get_uint16_from(name, "TLS_CIPHER_0x", pcipher);
574 }
575 
tls_proto_get_cipher_name(tls_proto_conf_t * conf,apr_uint16_t id,apr_pool_t * pool)576 const char *tls_proto_get_cipher_name(
577     tls_proto_conf_t *conf, apr_uint16_t id, apr_pool_t *pool)
578 {
579     tls_cipher_t *cipher = apr_hash_get(conf->known_ciphers_by_id, &id, sizeof(apr_uint16_t));
580     if (cipher) {
581         return cipher->name;
582     }
583     return apr_psprintf(pool, "TLS_CIPHER_0x%04x", id);
584 }
585 
tls_proto_get_rustls_suites(tls_proto_conf_t * conf,const apr_array_header_t * ids,apr_pool_t * pool)586 apr_array_header_t *tls_proto_get_rustls_suites(
587     tls_proto_conf_t *conf, const apr_array_header_t *ids, apr_pool_t *pool)
588 {
589     apr_array_header_t *suites;
590     rustls_cipher_t *rcipher;
591     apr_uint16_t id;
592     int i;
593 
594     suites = apr_array_make(pool, ids->nelts, sizeof(const rustls_supported_ciphersuite*));
595     for (i = 0; i < ids->nelts; ++i) {
596         id = APR_ARRAY_IDX(ids, i, apr_uint16_t);
597         rcipher = apr_hash_get(conf->rustls_ciphers_by_id, &id, sizeof(apr_uint16_t));
598         if (rcipher) {
599             APR_ARRAY_PUSH(suites, const rustls_supported_ciphersuite *) = rcipher->rustls_suite;
600         }
601     }
602     return suites;
603 }
604