]>
Commit | Line | Data |
---|---|---|
536dbc00 MW |
1 | /* |
2 | * Copyright (C) 2010 Martin Willi | |
3 | * Copyright (C) 2010 revosec AG | |
4 | * | |
5 | * This program is free software; you can redistribute it and/or modify it | |
6 | * under the terms of the GNU General Public License as published by the | |
7 | * Free Software Foundation; either version 2 of the License, or (at your | |
8 | * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. | |
9 | * | |
10 | * This program is distributed in the hope that it will be useful, but | |
11 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
12 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
13 | * for more details. | |
14 | */ | |
15 | ||
16 | #include "tls_crypto.h" | |
17 | ||
0f82a470 | 18 | #include <debug.h> |
18010de2 | 19 | |
4657b3a4 AS |
20 | ENUM_BEGIN(tls_cipher_suite_names, TLS_NULL_WITH_NULL_NULL, |
21 | TLS_DH_anon_WITH_3DES_EDE_CBC_SHA, | |
22 | "TLS_NULL_WITH_NULL_NULL", | |
23 | "TLS_RSA_WITH_NULL_MD5", | |
24 | "TLS_RSA_WITH_NULL_SHA", | |
25 | "TLS_RSA_EXPORT_WITH_RC4_40_MD5", | |
26 | "TLS_RSA_WITH_RC4_128_MD5", | |
27 | "TLS_RSA_WITH_RC4_128_SHA", | |
28 | "TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5", | |
29 | "TLS_RSA_WITH_IDEA_CBC_SHA", | |
30 | "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA", | |
31 | "TLS_RSA_WITH_DES_CBC_SHA", | |
32 | "TLS_RSA_WITH_3DES_EDE_CBC_SHA", | |
33 | "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", | |
34 | "TLS_DH_DSS_WITH_DES_CBC_SHA", | |
35 | "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA", | |
36 | "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", | |
37 | "TLS_DH_RSA_WITH_DES_CBC_SHA", | |
38 | "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA", | |
39 | "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", | |
37d2d7e1 | 40 | "TLS_DHE_DSS_WITH_DES_CBC_SHA", |
4657b3a4 AS |
41 | "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA", |
42 | "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", | |
43 | "TLS_DHE_RSA_WITH_DES_CBC_SHA", | |
44 | "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA", | |
45 | "TLS_DH_anon_EXPORT_WITH_RC4_40_MD5", | |
46 | "TLS_DH_anon_WITH_RC4_128_MD5", | |
47 | "TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA", | |
48 | "TLS_DH_anon_WITH_DES_CBC_SHA", | |
49 | "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA"); | |
50 | ENUM_NEXT(tls_cipher_suite_names, TLS_KRB5_WITH_DES_CBC_SHA, | |
51 | TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA, | |
52 | TLS_DH_anon_WITH_3DES_EDE_CBC_SHA, | |
53 | "TLS_KRB5_WITH_DES_CBC_SHA", | |
54 | "TLS_KRB5_WITH_3DES_EDE_CBC_SHA", | |
55 | "TLS_KRB5_WITH_RC4_128_SHA", | |
56 | "TLS_KRB5_WITH_IDEA_CBC_SHA", | |
57 | "TLS_KRB5_WITH_DES_CBC_MD5", | |
58 | "TLS_KRB5_WITH_3DES_EDE_CBC_MD5", | |
59 | "TLS_KRB5_WITH_RC4_128_MD5", | |
60 | "TLS_KRB5_WITH_IDEA_CBC_MD5", | |
61 | "TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA", | |
37d2d7e1 | 62 | "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA", |
4657b3a4 AS |
63 | "TLS_KRB5_EXPORT_WITH_RC4_40_SHA", |
64 | "TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5", | |
65 | "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5", | |
66 | "TLS_KRB5_EXPORT_WITH_RC4_40_MD5", | |
67 | "TLS_PSK_WITH_NULL_SHA", | |
68 | "TLS_DHE_PSK_WITH_NULL_SHA", | |
69 | "TLS_RSA_PSK_WITH_NULL_SHA", | |
70 | "TLS_RSA_WITH_AES_128_CBC_SHA", | |
71 | "TLS_DH_DSS_WITH_AES_128_CBC_SHA", | |
72 | "TLS_DH_RSA_WITH_AES_128_CBC_SHA", | |
73 | "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", | |
74 | "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", | |
75 | "TLS_DH_anon_WITH_AES_128_CBC_SHA", | |
76 | "TLS_RSA_WITH_AES_256_CBC_SHA", | |
77 | "TLS_DH_DSS_WITH_AES_256_CBC_SHA", | |
78 | "TLS_DH_RSA_WITH_AES_256_CBC_SHA", | |
79 | "TLS_DHE_DSS_WITH_AES_256_CBC_SHA", | |
80 | "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", | |
81 | "TLS_DH_anon_WITH_AES_256_CBC_SHA", | |
82 | "TLS_RSA_WITH_NULL_SHA256", | |
83 | "TLS_RSA_WITH_AES_128_CBC_SHA256 ", | |
84 | "TLS_RSA_WITH_AES_256_CBC_SHA256", | |
85 | "TLS_DH_DSS_WITH_AES_128_CBC_SHA256", | |
86 | "TLS_DH_RSA_WITH_AES_128_CBC_SHA256", | |
87 | "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", | |
88 | "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA", | |
89 | "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA", | |
90 | "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA", | |
91 | "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA", | |
37d2d7e1 | 92 | "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA", |
4657b3a4 AS |
93 | "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA"); |
94 | ENUM_NEXT(tls_cipher_suite_names, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, | |
95 | TLS_DH_anon_WITH_AES_256_CBC_SHA256, | |
96 | TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA, | |
97 | "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", | |
98 | "TLS_DH_DSS_WITH_AES_256_CBC_SHA256", | |
99 | "TLS_DH_RSA_WITH_AES_256_CBC_SHA256", | |
100 | "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", | |
101 | "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", | |
102 | "TLS_DH_anon_WITH_AES_128_CBC_SHA256", | |
103 | "TLS_DH_anon_WITH_AES_256_CBC_SHA256"); | |
104 | ENUM_NEXT(tls_cipher_suite_names, TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, | |
37d2d7e1 | 105 | TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256, |
4657b3a4 AS |
106 | TLS_DH_anon_WITH_AES_256_CBC_SHA256, |
107 | "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA", | |
108 | "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA", | |
109 | "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA", | |
110 | "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA", | |
111 | "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA", | |
112 | "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA", | |
113 | "TLS_PSK_WITH_RC4_128_SHA", | |
114 | "TLS_PSK_WITH_3DES_EDE_CBC_SHA2", | |
115 | "TLS_PSK_WITH_AES_128_CBC_SHA", | |
116 | "TLS_PSK_WITH_AES_256_CBC_SHA", | |
117 | "TLS_DHE_PSK_WITH_RC4_128_SHA", | |
118 | "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA", | |
119 | "TLS_DHE_PSK_WITH_AES_128_CBC_SHA", | |
120 | "TLS_DHE_PSK_WITH_AES_256_CBC_SHA2", | |
121 | "TLS_RSA_PSK_WITH_RC4_128_SHA", | |
122 | "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA", | |
123 | "TLS_RSA_PSK_WITH_AES_128_CBC_SHA", | |
124 | "TLS_RSA_PSK_WITH_AES_256_CBC_SHA", | |
125 | "TLS_RSA_WITH_SEED_CBC_SHA", | |
126 | "TLS_DH_DSS_WITH_SEED_CBC_SHA", | |
127 | "TLS_DH_RSA_WITH_SEED_CBC_SHA", | |
128 | "TLS_DHE_DSS_WITH_SEED_CBC_SHA", | |
129 | "TLS_DHE_RSA_WITH_SEED_CBC_SHA", | |
130 | "TLS_DH_anon_WITH_SEED_CBC_SHA", | |
131 | "TLS_RSA_WITH_AES_128_GCM_SHA256", | |
132 | "TLS_RSA_WITH_AES_256_GCM_SHA384", | |
133 | "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", | |
134 | "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", | |
135 | "TLS_DH_RSA_WITH_AES_128_GCM_SHA256", | |
136 | "TLS_DH_RSA_WITH_AES_256_GCM_SHA384", | |
137 | "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256", | |
138 | "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384", | |
139 | "TLS_DH_DSS_WITH_AES_128_GCM_SHA256", | |
140 | "TLS_DH_DSS_WITH_AES_256_GCM_SHA384", | |
141 | "TLS_DH_anon_WITH_AES_128_GCM_SHA256", | |
142 | "TLS_DH_anon_WITH_AES_256_GCM_SHA384", | |
143 | "TLS_PSK_WITH_AES_128_GCM_SHA256", | |
144 | "TLS_PSK_WITH_AES_256_GCM_SHA384", | |
145 | "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256", | |
146 | "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384", | |
147 | "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256", | |
148 | "TLS_RSA_PSK_WITH_AES_256_GCM_SHA384", | |
149 | "TLS_PSK_WITH_AES_128_CBC_SHA256", | |
150 | "TLS_PSK_WITH_AES_256_CBC_SHA384", | |
151 | "TLS_PSK_WITH_NULL_SHA256", | |
152 | "TLS_PSK_WITH_NULL_SHA384", | |
153 | "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256", | |
154 | "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384", | |
155 | "TLS_DHE_PSK_WITH_NULL_SHA256", | |
156 | "TLS_DHE_PSK_WITH_NULL_SHA384", | |
157 | "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256", | |
158 | "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384", | |
159 | "TLS_RSA_PSK_WITH_NULL_SHA256", | |
160 | "TLS_RSA_PSK_WITH_NULL_SHA384", | |
161 | "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256", | |
162 | "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256", | |
163 | "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256", | |
164 | "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256", | |
165 | "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", | |
166 | "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256", | |
167 | "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256", | |
168 | "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256", | |
169 | "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256", | |
170 | "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256", | |
171 | "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256", | |
172 | "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256"); | |
173 | ENUM_NEXT(tls_cipher_suite_names, TLS_EMPTY_RENEGOTIATION_INFO_SCSV, | |
37d2d7e1 | 174 | TLS_EMPTY_RENEGOTIATION_INFO_SCSV, |
4657b3a4 AS |
175 | TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256, |
176 | "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"); | |
177 | ENUM_NEXT(tls_cipher_suite_names, TLS_ECDH_ECDSA_WITH_NULL_SHA, | |
37d2d7e1 | 178 | TLS_ECDHE_PSK_WITH_NULL_SHA384, |
4657b3a4 AS |
179 | TLS_EMPTY_RENEGOTIATION_INFO_SCSV, |
180 | "TLS_ECDH_ECDSA_WITH_NULL_SHA", | |
181 | "TLS_ECDH_ECDSA_WITH_RC4_128_SHA", | |
182 | "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA", | |
183 | "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", | |
184 | "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", | |
185 | "TLS_ECDHE_ECDSA_WITH_NULL_SHA", | |
186 | "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", | |
187 | "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", | |
188 | "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", | |
189 | "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", | |
190 | "TLS_ECDH_RSA_WITH_NULL_SHA", | |
191 | "TLS_ECDH_RSA_WITH_RC4_128_SHA", | |
192 | "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA", | |
193 | "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", | |
194 | "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", | |
195 | "TLS_ECDHE_RSA_WITH_NULL_SHA", | |
196 | "TLS_ECDHE_RSA_WITH_RC4_128_SHA", | |
197 | "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", | |
198 | "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", | |
199 | "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", | |
200 | "TLS_ECDH_anon_WITH_NULL_SHA", | |
201 | "TLS_ECDH_anon_WITH_RC4_128_SHA", | |
202 | "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA", | |
203 | "TLS_ECDH_anon_WITH_AES_128_CBC_SHA", | |
204 | "TLS_ECDH_anon_WITH_AES_256_CBC_SHA", | |
205 | "TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA", | |
206 | "TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA", | |
207 | "TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA", | |
208 | "TLS_SRP_SHA_WITH_AES_128_CBC_SHA", | |
209 | "TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA", | |
210 | "TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA", | |
211 | "TLS_SRP_SHA_WITH_AES_256_CBC_SHA", | |
212 | "TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA", | |
213 | "TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA", | |
214 | "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", | |
215 | "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", | |
216 | "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", | |
217 | "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", | |
218 | "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", | |
219 | "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", | |
220 | "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", | |
221 | "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", | |
222 | "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", | |
223 | "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", | |
224 | "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", | |
225 | "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384", | |
226 | "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", | |
227 | "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", | |
228 | "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", | |
229 | "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384", | |
230 | "TLS_ECDHE_PSK_WITH_RC4_128_SHA", | |
231 | "TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA", | |
232 | "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA", | |
233 | "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA", | |
234 | "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256", | |
235 | "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384", | |
236 | "TLS_ECDHE_PSK_WITH_NULL_SHA", | |
237 | "TLS_ECDHE_PSK_WITH_NULL_SHA256", | |
238 | "TLS_ECDHE_PSK_WITH_NULL_SHA384"); | |
239 | ENUM_END(tls_cipher_suite_names, TLS_ECDHE_PSK_WITH_NULL_SHA384); | |
240 | ||
9dd2ca92 MW |
241 | ENUM(tls_hash_algorithm_names, TLS_HASH_NONE, TLS_HASH_SHA512, |
242 | "NONE", | |
243 | "MD5", | |
244 | "SHA1", | |
245 | "SHA224", | |
246 | "SHA256", | |
247 | "SHA384", | |
248 | "SHA512", | |
249 | ); | |
250 | ||
251 | ENUM(tls_signature_algorithm_names, TLS_SIG_RSA, TLS_SIG_ECDSA, | |
252 | "RSA", | |
253 | "DSA", | |
254 | "ECDSA", | |
255 | ); | |
256 | ||
99dcaea9 MW |
257 | ENUM_BEGIN(tls_client_certificate_type_names, |
258 | TLS_RSA_SIGN, TLS_DSS_EPHEMERAL_DH, | |
259 | "RSA_SIGN", | |
260 | "DSA_SIGN", | |
261 | "RSA_FIXED_DH", | |
262 | "DSS_FIXED_DH", | |
263 | "RSA_EPHEMERAL_DH", | |
264 | "DSS_EPHEMERAL_DH"); | |
265 | ENUM_NEXT(tls_client_certificate_type_names, | |
266 | TLS_FORTEZZA_DMS, TLS_FORTEZZA_DMS, TLS_DSS_EPHEMERAL_DH, | |
267 | "FORTEZZA_DMS"); | |
268 | ENUM_NEXT(tls_client_certificate_type_names, | |
269 | TLS_ECDSA_SIGN, TLS_ECDSA_FIXED_ECDH, TLS_FORTEZZA_DMS, | |
270 | "ECDSA_SIGN", | |
271 | "RSA_FIXED_ECDH", | |
272 | "ECDSA_FIXED_ECDH"); | |
273 | ENUM_END(tls_client_certificate_type_names, TLS_ECDSA_FIXED_ECDH); | |
274 | ||
691ca54d MW |
275 | ENUM(tls_ecc_curve_type_names, TLS_ECC_EXPLICIT_PRIME, TLS_ECC_NAMED_CURVE, |
276 | "EXPLICIT_PRIME", | |
277 | "EXPLICIT_CHAR2", | |
278 | "NAMED_CURVE", | |
279 | ); | |
280 | ||
281 | ENUM(tls_named_curve_names, TLS_SECT163K1, TLS_SECP521R1, | |
282 | "SECT163K1", | |
283 | "SECT163R1", | |
284 | "SECT163R2", | |
285 | "SECT193R1", | |
286 | "SECT193R2", | |
287 | "SECT233K1", | |
288 | "SECT233R1", | |
289 | "SECT239K1", | |
290 | "SECT283K1", | |
291 | "SECT283R1", | |
292 | "SECT409K1", | |
293 | "SECT409R1", | |
294 | "SECT571K1", | |
295 | "SECT571R1", | |
296 | "SECP160K1", | |
297 | "SECP160R1", | |
298 | "SECP160R2", | |
299 | "SECP192K1", | |
300 | "SECP192R1", | |
301 | "SECP224K1", | |
302 | "SECP224R1", | |
303 | "SECP256K1", | |
304 | "SECP256R1", | |
305 | "SECP384R1", | |
306 | "SECP521R1", | |
307 | ); | |
308 | ||
ec7d4e70 | 309 | ENUM(tls_ansi_point_format_names, TLS_ANSI_COMPRESSED, TLS_ANSI_HYBRID_Y, |
e6cce7ff MW |
310 | "compressed", |
311 | "compressed y", | |
312 | "uncompressed", | |
313 | "uncompressed y", | |
314 | "hybrid", | |
315 | "hybrid y", | |
316 | ); | |
99dcaea9 | 317 | |
02281c87 MW |
318 | ENUM(tls_ec_point_format_names, |
319 | TLS_EC_POINT_UNCOMPRESSED, TLS_EC_POINT_ANSIX962_COMPRESSED_CHAR2, | |
320 | "uncompressed", | |
321 | "ansiX962 compressed prime", | |
322 | "ansiX962 compressed char2", | |
323 | ); | |
324 | ||
536dbc00 MW |
325 | typedef struct private_tls_crypto_t private_tls_crypto_t; |
326 | ||
327 | /** | |
328 | * Private data of an tls_crypto_t object. | |
329 | */ | |
330 | struct private_tls_crypto_t { | |
331 | ||
332 | /** | |
333 | * Public tls_crypto_t interface. | |
334 | */ | |
335 | tls_crypto_t public; | |
18010de2 | 336 | |
dc9f34be MW |
337 | /** |
338 | * Protection layer | |
339 | */ | |
340 | tls_protection_t *protection; | |
341 | ||
18010de2 MW |
342 | /** |
343 | * List of supported/acceptable cipher suites | |
344 | */ | |
345 | tls_cipher_suite_t *suites; | |
346 | ||
347 | /** | |
348 | * Number of supported suites | |
349 | */ | |
350 | int suite_count; | |
351 | ||
352 | /** | |
353 | * Selected cipher suite | |
354 | */ | |
355 | tls_cipher_suite_t suite; | |
356 | ||
4254257f MW |
357 | /** |
358 | * RSA supported? | |
359 | */ | |
360 | bool rsa; | |
361 | ||
362 | /** | |
363 | * ECDSA supported? | |
364 | */ | |
365 | bool ecdsa; | |
366 | ||
18010de2 MW |
367 | /** |
368 | * TLS context | |
369 | */ | |
370 | tls_t *tls; | |
371 | ||
6a5c86b7 MW |
372 | /** |
373 | * TLS session cache | |
374 | */ | |
375 | tls_cache_t *cache; | |
376 | ||
84d67ead MW |
377 | /** |
378 | * All handshake data concatentated | |
379 | */ | |
380 | chunk_t handshake; | |
381 | ||
18010de2 MW |
382 | /** |
383 | * Connection state TLS PRF | |
384 | */ | |
385 | tls_prf_t *prf; | |
84543e6e MW |
386 | |
387 | /** | |
388 | * Signer instance for inbound traffic | |
389 | */ | |
390 | signer_t *signer_in; | |
391 | ||
392 | /** | |
393 | * Signer instance for outbound traffic | |
394 | */ | |
395 | signer_t *signer_out; | |
396 | ||
397 | /** | |
398 | * Crypter instance for inbound traffic | |
399 | */ | |
400 | crypter_t *crypter_in; | |
401 | ||
402 | /** | |
403 | * Crypter instance for outbound traffic | |
404 | */ | |
405 | crypter_t *crypter_out; | |
406 | ||
407 | /** | |
408 | * IV for input decryption, if < TLSv1.2 | |
409 | */ | |
410 | chunk_t iv_in; | |
411 | ||
412 | /** | |
413 | * IV for output decryption, if < TLSv1.2 | |
414 | */ | |
415 | chunk_t iv_out; | |
51313a39 MW |
416 | |
417 | /** | |
a6444fcd | 418 | * EAP-[T]TLS MSK |
51313a39 MW |
419 | */ |
420 | chunk_t msk; | |
a6444fcd AS |
421 | |
422 | /** | |
423 | * ASCII string constant used as seed for EAP-[T]TLS MSK PRF | |
424 | */ | |
425 | char *msk_label; | |
536dbc00 MW |
426 | }; |
427 | ||
84543e6e MW |
428 | typedef struct { |
429 | tls_cipher_suite_t suite; | |
4cdade5a MW |
430 | key_type_t key; |
431 | diffie_hellman_group_t dh; | |
84543e6e MW |
432 | hash_algorithm_t hash; |
433 | pseudo_random_function_t prf; | |
434 | integrity_algorithm_t mac; | |
435 | encryption_algorithm_t encr; | |
436 | size_t encr_size; | |
437 | } suite_algs_t; | |
438 | ||
439 | /** | |
440 | * Mapping suites to a set of algorithms | |
441 | */ | |
442 | static suite_algs_t suite_algs[] = { | |
2066918d MW |
443 | { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, |
444 | KEY_ECDSA, ECP_256_BIT, | |
ed57dfca | 445 | HASH_SHA256, PRF_HMAC_SHA2_256, |
2066918d MW |
446 | AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 16 |
447 | }, | |
448 | { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, | |
449 | KEY_ECDSA, ECP_256_BIT, | |
450 | HASH_SHA256, PRF_HMAC_SHA2_256, | |
451 | AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 16 | |
452 | }, | |
453 | { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, | |
454 | KEY_ECDSA, ECP_384_BIT, | |
ed57dfca | 455 | HASH_SHA256, PRF_HMAC_SHA2_256, |
2066918d MW |
456 | AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 32 |
457 | }, | |
458 | { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, | |
459 | KEY_ECDSA, ECP_384_BIT, | |
460 | HASH_SHA384, PRF_HMAC_SHA2_384, | |
461 | AUTH_HMAC_SHA2_384_384, ENCR_AES_CBC, 32 | |
462 | }, | |
463 | { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, | |
f9c0cf86 | 464 | KEY_RSA, ECP_256_BIT, |
ed57dfca | 465 | HASH_SHA256, PRF_HMAC_SHA2_256, |
2066918d MW |
466 | AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 16 |
467 | }, | |
468 | { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, | |
f9c0cf86 | 469 | KEY_RSA, ECP_256_BIT, |
2066918d MW |
470 | HASH_SHA256, PRF_HMAC_SHA2_256, |
471 | AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 16 | |
472 | }, | |
473 | { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, | |
f9c0cf86 | 474 | KEY_RSA, ECP_384_BIT, |
ed57dfca | 475 | HASH_SHA256, PRF_HMAC_SHA2_256, |
2066918d MW |
476 | AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 32 |
477 | }, | |
478 | { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, | |
f9c0cf86 | 479 | KEY_RSA, ECP_384_BIT, |
2066918d MW |
480 | HASH_SHA384, PRF_HMAC_SHA2_384, |
481 | AUTH_HMAC_SHA2_384_384, ENCR_AES_CBC, 32 | |
482 | }, | |
ef0a8e58 | 483 | { TLS_DHE_RSA_WITH_AES_128_CBC_SHA, |
4cdade5a | 484 | KEY_RSA, MODP_2048_BIT, |
ed57dfca | 485 | HASH_SHA256,PRF_HMAC_SHA2_256, |
ef0a8e58 MW |
486 | AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 16 |
487 | }, | |
488 | { TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, | |
4cdade5a MW |
489 | KEY_RSA, MODP_3072_BIT, |
490 | HASH_SHA256, PRF_HMAC_SHA2_256, | |
ef0a8e58 MW |
491 | AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 16 |
492 | }, | |
493 | { TLS_DHE_RSA_WITH_AES_256_CBC_SHA, | |
4cdade5a | 494 | KEY_RSA, MODP_3072_BIT, |
ed57dfca | 495 | HASH_SHA256, PRF_HMAC_SHA2_256, |
ef0a8e58 MW |
496 | AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 32 |
497 | }, | |
498 | { TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, | |
4cdade5a MW |
499 | KEY_RSA, MODP_4096_BIT, |
500 | HASH_SHA256, PRF_HMAC_SHA2_256, | |
ef0a8e58 MW |
501 | AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 32 |
502 | }, | |
503 | { TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, | |
4cdade5a | 504 | KEY_RSA, MODP_2048_BIT, |
ed57dfca | 505 | HASH_SHA256, PRF_HMAC_SHA2_256, |
ef0a8e58 MW |
506 | AUTH_HMAC_SHA1_160, ENCR_CAMELLIA_CBC, 16 |
507 | }, | |
508 | { TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, | |
4cdade5a MW |
509 | KEY_RSA, MODP_3072_BIT, |
510 | HASH_SHA256, PRF_HMAC_SHA2_256, | |
ef0a8e58 MW |
511 | AUTH_HMAC_SHA2_256_256, ENCR_CAMELLIA_CBC, 16 |
512 | }, | |
513 | { TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, | |
4cdade5a | 514 | KEY_RSA, MODP_3072_BIT, |
ed57dfca | 515 | HASH_SHA256, PRF_HMAC_SHA2_256, |
ef0a8e58 MW |
516 | AUTH_HMAC_SHA1_160, ENCR_CAMELLIA_CBC, 32 |
517 | }, | |
518 | { TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, | |
4cdade5a MW |
519 | KEY_RSA, MODP_4096_BIT, |
520 | HASH_SHA256, PRF_HMAC_SHA2_256, | |
ef0a8e58 MW |
521 | AUTH_HMAC_SHA2_256_256, ENCR_CAMELLIA_CBC, 32 |
522 | }, | |
523 | { TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA, | |
4cdade5a | 524 | KEY_RSA, MODP_2048_BIT, |
ed57dfca | 525 | HASH_SHA256, PRF_HMAC_SHA2_256, |
ef0a8e58 MW |
526 | AUTH_HMAC_SHA1_160, ENCR_3DES, 0 |
527 | }, | |
84543e6e | 528 | { TLS_RSA_WITH_AES_128_CBC_SHA, |
4cdade5a | 529 | KEY_RSA, MODP_NONE, |
ed57dfca | 530 | HASH_SHA256, PRF_HMAC_SHA2_256, |
6e413d9c MW |
531 | AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 16 |
532 | }, | |
533 | { TLS_RSA_WITH_AES_128_CBC_SHA256, | |
4cdade5a MW |
534 | KEY_RSA, MODP_NONE, |
535 | HASH_SHA256, PRF_HMAC_SHA2_256, | |
6e413d9c | 536 | AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 16 |
84543e6e MW |
537 | }, |
538 | { TLS_RSA_WITH_AES_256_CBC_SHA, | |
4cdade5a | 539 | KEY_RSA, MODP_NONE, |
ed57dfca | 540 | HASH_SHA256, PRF_HMAC_SHA2_256, |
6e413d9c | 541 | AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 32 |
84543e6e | 542 | }, |
6e413d9c | 543 | { TLS_RSA_WITH_AES_256_CBC_SHA256, |
4cdade5a MW |
544 | KEY_RSA, MODP_NONE, |
545 | HASH_SHA256, PRF_HMAC_SHA2_256, | |
6e413d9c | 546 | AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 32 |
84543e6e | 547 | }, |
6e413d9c | 548 | { TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, |
4cdade5a | 549 | KEY_RSA, MODP_NONE, |
ed57dfca | 550 | HASH_SHA256, PRF_HMAC_SHA2_256, |
6e413d9c MW |
551 | AUTH_HMAC_SHA1_160, ENCR_CAMELLIA_CBC, 16 |
552 | }, | |
553 | { TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, | |
4cdade5a MW |
554 | KEY_RSA, MODP_NONE, |
555 | HASH_SHA256, PRF_HMAC_SHA2_256, | |
6e413d9c MW |
556 | AUTH_HMAC_SHA2_256_256, ENCR_CAMELLIA_CBC, 16 |
557 | }, | |
558 | { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, | |
4cdade5a | 559 | KEY_RSA, MODP_NONE, |
ed57dfca | 560 | HASH_SHA256, PRF_HMAC_SHA2_256, |
6e413d9c MW |
561 | AUTH_HMAC_SHA1_160, ENCR_CAMELLIA_CBC, 32 |
562 | }, | |
563 | { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, | |
4cdade5a MW |
564 | KEY_RSA, MODP_NONE, |
565 | HASH_SHA256, PRF_HMAC_SHA2_256, | |
6e413d9c | 566 | AUTH_HMAC_SHA2_256_256, ENCR_CAMELLIA_CBC, 32 |
84543e6e | 567 | }, |
2066918d MW |
568 | { TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, |
569 | KEY_ECDSA, ECP_256_BIT, | |
ed57dfca | 570 | HASH_SHA256, PRF_HMAC_SHA2_256, |
2066918d MW |
571 | AUTH_HMAC_SHA1_160, ENCR_3DES, 0 |
572 | }, | |
573 | { TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, | |
a03eebdf | 574 | KEY_RSA, ECP_256_BIT, |
ed57dfca | 575 | HASH_SHA256, PRF_HMAC_SHA2_256, |
2066918d MW |
576 | AUTH_HMAC_SHA1_160, ENCR_3DES, 0 |
577 | }, | |
2bf0e74c | 578 | { TLS_RSA_WITH_3DES_EDE_CBC_SHA, |
4cdade5a | 579 | KEY_RSA, MODP_NONE, |
ed57dfca | 580 | HASH_SHA256, PRF_HMAC_SHA2_256, |
2bf0e74c MW |
581 | AUTH_HMAC_SHA1_160, ENCR_3DES, 0 |
582 | }, | |
2066918d MW |
583 | { TLS_ECDHE_ECDSA_WITH_NULL_SHA, |
584 | KEY_ECDSA, ECP_256_BIT, | |
ed57dfca | 585 | HASH_SHA256, PRF_HMAC_SHA2_256, |
2066918d MW |
586 | AUTH_HMAC_SHA1_160, ENCR_NULL, 0 |
587 | }, | |
588 | { TLS_ECDHE_RSA_WITH_NULL_SHA, | |
589 | KEY_ECDSA, ECP_256_BIT, | |
ed57dfca | 590 | HASH_SHA256, PRF_HMAC_SHA2_256, |
2066918d MW |
591 | AUTH_HMAC_SHA1_160, ENCR_NULL, 0 |
592 | }, | |
2bf0e74c | 593 | { TLS_RSA_WITH_NULL_SHA, |
4cdade5a | 594 | KEY_RSA, MODP_NONE, |
ed57dfca | 595 | HASH_SHA256, PRF_HMAC_SHA2_256, |
2bf0e74c MW |
596 | AUTH_HMAC_SHA1_160, ENCR_NULL, 0 |
597 | }, | |
598 | { TLS_RSA_WITH_NULL_SHA256, | |
4cdade5a MW |
599 | KEY_RSA, MODP_NONE, |
600 | HASH_SHA256, PRF_HMAC_SHA2_256, | |
2bf0e74c MW |
601 | AUTH_HMAC_SHA2_256_256, ENCR_NULL, 0 |
602 | }, | |
603 | { TLS_RSA_WITH_NULL_MD5, | |
4cdade5a | 604 | KEY_RSA, MODP_NONE, |
ed57dfca | 605 | HASH_SHA256, PRF_HMAC_SHA2_256, |
2bf0e74c MW |
606 | AUTH_HMAC_MD5_128, ENCR_NULL, 0 |
607 | }, | |
84543e6e MW |
608 | }; |
609 | ||
610 | /** | |
f3bb1bd0 | 611 | * Look up algorithms by a suite |
84543e6e MW |
612 | */ |
613 | static suite_algs_t *find_suite(tls_cipher_suite_t suite) | |
614 | { | |
615 | int i; | |
616 | ||
617 | for (i = 0; i < countof(suite_algs); i++) | |
618 | { | |
619 | if (suite_algs[i].suite == suite) | |
620 | { | |
621 | return &suite_algs[i]; | |
622 | } | |
623 | } | |
624 | return NULL; | |
625 | } | |
626 | ||
18010de2 | 627 | /** |
a2bfc45b | 628 | * Filter a suite list using a transform enumerator |
18010de2 | 629 | */ |
a2bfc45b MW |
630 | static void filter_suite(private_tls_crypto_t *this, |
631 | suite_algs_t suites[], int *count, int offset, | |
632 | enumerator_t*(*create_enumerator)(crypto_factory_t*)) | |
536dbc00 | 633 | { |
5932f41f | 634 | const char *plugin_name; |
a2bfc45b | 635 | suite_algs_t current; |
f10e7234 | 636 | int *current_alg, i, remaining = 0; |
a2bfc45b | 637 | enumerator_t *enumerator; |
536dbc00 | 638 | |
a2bfc45b | 639 | memset(¤t, 0, sizeof(current)); |
f10e7234 AS |
640 | current_alg = (int*)((char*)¤t + offset); |
641 | ||
a2bfc45b | 642 | for (i = 0; i < *count; i++) |
536dbc00 | 643 | { |
a2bfc45b | 644 | enumerator = create_enumerator(lib->crypto); |
f10e7234 | 645 | while (enumerator->enumerate(enumerator, current_alg, &plugin_name)) |
536dbc00 | 646 | { |
a2bfc45b MW |
647 | if ((suites[i].encr == ENCR_NULL || |
648 | !current.encr || current.encr == suites[i].encr) && | |
649 | (!current.mac || current.mac == suites[i].mac) && | |
650 | (!current.prf || current.prf == suites[i].prf) && | |
4e68c1cf MW |
651 | (!current.hash || current.hash == suites[i].hash) && |
652 | (suites[i].dh == MODP_NONE || | |
653 | !current.dh || current.dh == suites[i].dh)) | |
536dbc00 | 654 | { |
a2bfc45b MW |
655 | suites[remaining] = suites[i]; |
656 | remaining++; | |
657 | break; | |
536dbc00 MW |
658 | } |
659 | } | |
a2bfc45b | 660 | enumerator->destroy(enumerator); |
536dbc00 | 661 | } |
a2bfc45b MW |
662 | *count = remaining; |
663 | } | |
664 | ||
96b2fbcc MW |
665 | /** |
666 | * Purge NULL encryption cipher suites from list | |
667 | */ | |
668 | static void filter_null_suites(private_tls_crypto_t *this, | |
669 | suite_algs_t suites[], int *count) | |
670 | { | |
671 | int i, remaining = 0; | |
672 | ||
673 | for (i = 0; i < *count; i++) | |
674 | { | |
675 | if (suites[i].encr != ENCR_NULL) | |
676 | { | |
677 | suites[remaining] = suites[i]; | |
678 | remaining++; | |
679 | } | |
680 | } | |
681 | *count = remaining; | |
682 | } | |
683 | ||
4254257f MW |
684 | /** |
685 | * Purge suites using a given key type | |
686 | */ | |
687 | static void filter_key_suites(private_tls_crypto_t *this, | |
688 | suite_algs_t suites[], int *count, key_type_t key) | |
689 | { | |
690 | int i, remaining = 0; | |
691 | ||
692 | DBG2(DBG_TLS, "disabling %N suites, no backend found", key_type_names, key); | |
693 | for (i = 0; i < *count; i++) | |
694 | { | |
695 | if (suites[i].key != key) | |
696 | { | |
697 | suites[remaining] = suites[i]; | |
698 | remaining++; | |
699 | } | |
700 | } | |
701 | *count = remaining; | |
702 | } | |
703 | ||
24a5b935 MW |
704 | /** |
705 | * Filter suites by key exchange user config | |
706 | */ | |
707 | static void filter_key_exchange_config_suites(private_tls_crypto_t *this, | |
708 | suite_algs_t suites[], int *count) | |
709 | { | |
710 | enumerator_t *enumerator; | |
711 | int i, remaining = 0; | |
712 | char *token, *config; | |
713 | ||
5b0bcfb1 | 714 | config = lib->settings->get_str(lib->settings, "libtls.key_exchange", NULL); |
24a5b935 MW |
715 | if (config) |
716 | { | |
717 | for (i = 0; i < *count; i++) | |
718 | { | |
719 | enumerator = enumerator_create_token(config, ",", " "); | |
720 | while (enumerator->enumerate(enumerator, &token)) | |
721 | { | |
722 | if (strcaseeq(token, "ecdhe-ecdsa") && | |
723 | diffie_hellman_group_is_ec(suites[i].dh) && | |
724 | suites[i].key == KEY_ECDSA) | |
725 | { | |
726 | suites[remaining++] = suites[i]; | |
727 | break; | |
728 | } | |
729 | if (strcaseeq(token, "ecdhe-rsa") && | |
730 | diffie_hellman_group_is_ec(suites[i].dh) && | |
731 | suites[i].key == KEY_RSA) | |
732 | { | |
733 | suites[remaining++] = suites[i]; | |
734 | break; | |
735 | } | |
736 | if (strcaseeq(token, "dhe-rsa") && | |
737 | !diffie_hellman_group_is_ec(suites[i].dh) && | |
738 | suites[i].dh != MODP_NONE && | |
739 | suites[i].key == KEY_RSA) | |
740 | { | |
741 | suites[remaining++] = suites[i]; | |
742 | break; | |
743 | } | |
744 | if (strcaseeq(token, "rsa") && | |
745 | suites[i].dh == MODP_NONE && | |
746 | suites[i].key == KEY_RSA) | |
747 | { | |
748 | suites[remaining++] = suites[i]; | |
749 | break; | |
750 | } | |
751 | } | |
752 | enumerator->destroy(enumerator); | |
753 | } | |
754 | *count = remaining; | |
755 | } | |
756 | } | |
757 | ||
758 | /** | |
759 | * Filter suites by cipher user config | |
760 | */ | |
761 | static void filter_cipher_config_suites(private_tls_crypto_t *this, | |
762 | suite_algs_t suites[], int *count) | |
763 | { | |
764 | enumerator_t *enumerator; | |
765 | int i, remaining = 0; | |
766 | char *token, *config; | |
767 | ||
5b0bcfb1 | 768 | config = lib->settings->get_str(lib->settings, "libtls.cipher", NULL); |
24a5b935 MW |
769 | if (config) |
770 | { | |
771 | for (i = 0; i < *count; i++) | |
772 | { | |
773 | enumerator = enumerator_create_token(config, ",", " "); | |
774 | while (enumerator->enumerate(enumerator, &token)) | |
775 | { | |
776 | if (strcaseeq(token, "aes128") && | |
777 | suites[i].encr == ENCR_AES_CBC && | |
778 | suites[i].encr_size == 16) | |
779 | { | |
780 | suites[remaining++] = suites[i]; | |
781 | break; | |
782 | } | |
783 | if (strcaseeq(token, "aes256") && | |
784 | suites[i].encr == ENCR_AES_CBC && | |
785 | suites[i].encr_size == 32) | |
786 | { | |
787 | suites[remaining++] = suites[i]; | |
788 | break; | |
789 | } | |
790 | if (strcaseeq(token, "camellia128") && | |
791 | suites[i].encr == ENCR_CAMELLIA_CBC && | |
792 | suites[i].encr_size == 16) | |
793 | { | |
794 | suites[remaining++] = suites[i]; | |
795 | break; | |
796 | } | |
797 | if (strcaseeq(token, "camellia256") && | |
798 | suites[i].encr == ENCR_CAMELLIA_CBC && | |
799 | suites[i].encr_size == 32) | |
800 | { | |
801 | suites[remaining++] = suites[i]; | |
802 | break; | |
803 | } | |
804 | if (strcaseeq(token, "3des") && | |
805 | suites[i].encr == ENCR_3DES) | |
806 | { | |
807 | suites[remaining++] = suites[i]; | |
808 | break; | |
809 | } | |
810 | if (strcaseeq(token, "null") && | |
811 | suites[i].encr == ENCR_NULL) | |
812 | { | |
813 | suites[remaining++] = suites[i]; | |
814 | break; | |
815 | } | |
816 | } | |
817 | enumerator->destroy(enumerator); | |
818 | } | |
819 | *count = remaining; | |
820 | } | |
821 | } | |
822 | ||
823 | /** | |
824 | * Filter suites by mac user config | |
825 | */ | |
826 | static void filter_mac_config_suites(private_tls_crypto_t *this, | |
827 | suite_algs_t suites[], int *count) | |
828 | { | |
829 | enumerator_t *enumerator; | |
830 | int i, remaining = 0; | |
831 | char *token, *config; | |
832 | ||
5b0bcfb1 | 833 | config = lib->settings->get_str(lib->settings, "libtls.mac", NULL); |
24a5b935 MW |
834 | if (config) |
835 | { | |
836 | for (i = 0; i < *count; i++) | |
837 | { | |
838 | enumerator = enumerator_create_token(config, ",", " "); | |
839 | while (enumerator->enumerate(enumerator, &token)) | |
840 | { | |
841 | if (strcaseeq(token, "md5") && | |
1dabf5bf | 842 | suites[i].mac == AUTH_HMAC_MD5_128) |
24a5b935 MW |
843 | { |
844 | suites[remaining++] = suites[i]; | |
845 | break; | |
846 | } | |
847 | if (strcaseeq(token, "sha1") && | |
1dabf5bf | 848 | suites[i].mac == AUTH_HMAC_SHA1_160) |
24a5b935 MW |
849 | { |
850 | suites[remaining++] = suites[i]; | |
851 | break; | |
852 | } | |
853 | if (strcaseeq(token, "sha256") && | |
1dabf5bf | 854 | suites[i].mac == AUTH_HMAC_SHA2_256_256) |
24a5b935 MW |
855 | { |
856 | suites[remaining++] = suites[i]; | |
857 | break; | |
858 | } | |
859 | if (strcaseeq(token, "sha384") && | |
1dabf5bf | 860 | suites[i].mac == AUTH_HMAC_SHA2_384_384) |
24a5b935 MW |
861 | { |
862 | suites[remaining++] = suites[i]; | |
863 | break; | |
864 | } | |
865 | } | |
866 | enumerator->destroy(enumerator); | |
867 | } | |
868 | *count = remaining; | |
869 | } | |
870 | } | |
871 | ||
adb913ad MW |
872 | /** |
873 | * Filter for specific suites specified in strongswan.conf | |
874 | */ | |
875 | static void filter_specific_config_suites(private_tls_crypto_t *this, | |
876 | suite_algs_t suites[], int *count) | |
877 | { | |
878 | enumerator_t *enumerator; | |
879 | int i, remaining = 0, suite; | |
880 | char *token, *config; | |
881 | ||
5b0bcfb1 | 882 | config = lib->settings->get_str(lib->settings, "libtls.suites", NULL); |
adb913ad MW |
883 | if (config) |
884 | { | |
885 | for (i = 0; i < *count; i++) | |
886 | { | |
887 | enumerator = enumerator_create_token(config, ",", " "); | |
888 | while (enumerator->enumerate(enumerator, &token)) | |
889 | { | |
890 | suite = enum_from_name(tls_cipher_suite_names, token); | |
891 | if (suite == suites[i].suite) | |
892 | { | |
893 | suites[remaining++] = suites[i]; | |
894 | break; | |
895 | } | |
896 | } | |
897 | enumerator->destroy(enumerator); | |
898 | } | |
899 | *count = remaining; | |
900 | } | |
901 | } | |
902 | ||
a2bfc45b MW |
903 | /** |
904 | * Initialize the cipher suite list | |
905 | */ | |
96b2fbcc MW |
906 | static void build_cipher_suite_list(private_tls_crypto_t *this, |
907 | bool require_encryption) | |
a2bfc45b MW |
908 | { |
909 | suite_algs_t suites[countof(suite_algs)]; | |
910 | int count = countof(suite_algs), i; | |
536dbc00 | 911 | |
a2bfc45b | 912 | /* copy all suites */ |
536dbc00 MW |
913 | for (i = 0; i < count; i++) |
914 | { | |
a2bfc45b | 915 | suites[i] = suite_algs[i]; |
18010de2 | 916 | } |
96b2fbcc MW |
917 | if (require_encryption) |
918 | { | |
919 | filter_null_suites(this, suites, &count); | |
920 | } | |
4254257f MW |
921 | if (!this->rsa) |
922 | { | |
923 | filter_key_suites(this, suites, &count, KEY_RSA); | |
924 | } | |
925 | if (!this->ecdsa) | |
926 | { | |
927 | filter_key_suites(this, suites, &count, KEY_ECDSA); | |
928 | } | |
929 | ||
a2bfc45b MW |
930 | /* filter suite list by each algorithm */ |
931 | filter_suite(this, suites, &count, offsetof(suite_algs_t, encr), | |
932 | lib->crypto->create_crypter_enumerator); | |
933 | filter_suite(this, suites, &count, offsetof(suite_algs_t, mac), | |
934 | lib->crypto->create_signer_enumerator); | |
935 | filter_suite(this, suites, &count, offsetof(suite_algs_t, prf), | |
936 | lib->crypto->create_prf_enumerator); | |
937 | filter_suite(this, suites, &count, offsetof(suite_algs_t, hash), | |
938 | lib->crypto->create_hasher_enumerator); | |
4e68c1cf MW |
939 | filter_suite(this, suites, &count, offsetof(suite_algs_t, dh), |
940 | lib->crypto->create_dh_enumerator); | |
a2bfc45b | 941 | |
24a5b935 MW |
942 | /* filter suites with strongswan.conf options */ |
943 | filter_key_exchange_config_suites(this, suites, &count); | |
944 | filter_cipher_config_suites(this, suites, &count); | |
945 | filter_mac_config_suites(this, suites, &count); | |
adb913ad | 946 | filter_specific_config_suites(this, suites, &count); |
24a5b935 | 947 | |
56a1167b AS |
948 | free(this->suites); |
949 | this->suite_count = count; | |
950 | this->suites = malloc(sizeof(tls_cipher_suite_t) * count); | |
951 | ||
3c19b346 | 952 | DBG2(DBG_TLS, "%d supported TLS cipher suites:", count); |
a2bfc45b MW |
953 | for (i = 0; i < count; i++) |
954 | { | |
3c19b346 | 955 | DBG2(DBG_TLS, " %N", tls_cipher_suite_names, suites[i].suite); |
56a1167b | 956 | this->suites[i] = suites[i].suite; |
a2bfc45b | 957 | } |
18010de2 MW |
958 | } |
959 | ||
960 | METHOD(tls_crypto_t, get_cipher_suites, int, | |
961 | private_tls_crypto_t *this, tls_cipher_suite_t **suites) | |
962 | { | |
963 | *suites = this->suites; | |
964 | return this->suite_count; | |
965 | } | |
966 | ||
84543e6e MW |
967 | /** |
968 | * Create crypto primitives | |
969 | */ | |
4cdade5a | 970 | static bool create_ciphers(private_tls_crypto_t *this, suite_algs_t *algs) |
84543e6e | 971 | { |
84543e6e MW |
972 | DESTROY_IF(this->prf); |
973 | if (this->tls->get_version(this->tls) < TLS_1_2) | |
974 | { | |
975 | this->prf = tls_prf_create_10(); | |
976 | } | |
977 | else | |
978 | { | |
979 | this->prf = tls_prf_create_12(algs->prf); | |
980 | } | |
981 | if (!this->prf) | |
982 | { | |
3c19b346 | 983 | DBG1(DBG_TLS, "selected TLS PRF not supported"); |
84543e6e MW |
984 | return FALSE; |
985 | } | |
986 | ||
987 | DESTROY_IF(this->signer_in); | |
988 | DESTROY_IF(this->signer_out); | |
989 | this->signer_in = lib->crypto->create_signer(lib->crypto, algs->mac); | |
990 | this->signer_out = lib->crypto->create_signer(lib->crypto, algs->mac); | |
991 | if (!this->signer_in || !this->signer_out) | |
992 | { | |
3c19b346 | 993 | DBG1(DBG_TLS, "selected TLS MAC %N not supported", |
84543e6e MW |
994 | integrity_algorithm_names, algs->mac); |
995 | return FALSE; | |
996 | } | |
997 | ||
998 | DESTROY_IF(this->crypter_in); | |
999 | DESTROY_IF(this->crypter_out); | |
1000 | if (algs->encr == ENCR_NULL) | |
1001 | { | |
1002 | this->crypter_in = this->crypter_out = NULL; | |
1003 | } | |
1004 | else | |
1005 | { | |
1006 | this->crypter_in = lib->crypto->create_crypter(lib->crypto, | |
1007 | algs->encr, algs->encr_size); | |
1008 | this->crypter_out = lib->crypto->create_crypter(lib->crypto, | |
1009 | algs->encr, algs->encr_size); | |
1010 | if (!this->crypter_in || !this->crypter_out) | |
1011 | { | |
3c19b346 | 1012 | DBG1(DBG_TLS, "selected TLS crypter %N not supported", |
84543e6e MW |
1013 | encryption_algorithm_names, algs->encr); |
1014 | return FALSE; | |
1015 | } | |
1016 | } | |
1017 | return TRUE; | |
1018 | } | |
1019 | ||
18010de2 | 1020 | METHOD(tls_crypto_t, select_cipher_suite, tls_cipher_suite_t, |
4cdade5a MW |
1021 | private_tls_crypto_t *this, tls_cipher_suite_t *suites, int count, |
1022 | key_type_t key) | |
18010de2 | 1023 | { |
4cdade5a | 1024 | suite_algs_t *algs; |
18010de2 MW |
1025 | int i, j; |
1026 | ||
1027 | for (i = 0; i < this->suite_count; i++) | |
1028 | { | |
1029 | for (j = 0; j < count; j++) | |
1030 | { | |
1031 | if (this->suites[i] == suites[j]) | |
1032 | { | |
4cdade5a MW |
1033 | algs = find_suite(this->suites[i]); |
1034 | if (algs) | |
84543e6e | 1035 | { |
4cdade5a MW |
1036 | if (key == KEY_ANY || key == algs->key) |
1037 | { | |
1038 | if (create_ciphers(this, algs)) | |
1039 | { | |
1040 | this->suite = this->suites[i]; | |
1041 | return this->suite; | |
1042 | } | |
1043 | } | |
84543e6e | 1044 | } |
18010de2 MW |
1045 | } |
1046 | } | |
1047 | } | |
1048 | return 0; | |
1049 | } | |
1050 | ||
35d9c15d MW |
1051 | METHOD(tls_crypto_t, get_dh_group, diffie_hellman_group_t, |
1052 | private_tls_crypto_t *this) | |
1053 | { | |
1054 | suite_algs_t *algs; | |
1055 | ||
1056 | algs = find_suite(this->suite); | |
1057 | if (algs) | |
1058 | { | |
1059 | return algs->dh; | |
1060 | } | |
1061 | return MODP_NONE; | |
1062 | } | |
1063 | ||
d29a82a9 | 1064 | METHOD(tls_crypto_t, get_signature_algorithms, void, |
7e432eff | 1065 | private_tls_crypto_t *this, bio_writer_t *writer) |
d29a82a9 | 1066 | { |
7e432eff | 1067 | bio_writer_t *supported; |
d29a82a9 MW |
1068 | enumerator_t *enumerator; |
1069 | hash_algorithm_t alg; | |
1070 | tls_hash_algorithm_t hash; | |
5932f41f | 1071 | const char *plugin_name; |
d29a82a9 | 1072 | |
7e432eff | 1073 | supported = bio_writer_create(32); |
d29a82a9 | 1074 | enumerator = lib->crypto->create_hasher_enumerator(lib->crypto); |
5932f41f | 1075 | while (enumerator->enumerate(enumerator, &alg, &plugin_name)) |
d29a82a9 MW |
1076 | { |
1077 | switch (alg) | |
1078 | { | |
1079 | case HASH_MD5: | |
1080 | hash = TLS_HASH_MD5; | |
1081 | break; | |
1082 | case HASH_SHA1: | |
1083 | hash = TLS_HASH_SHA1; | |
1084 | break; | |
1085 | case HASH_SHA224: | |
1086 | hash = TLS_HASH_SHA224; | |
1087 | break; | |
1088 | case HASH_SHA256: | |
1089 | hash = TLS_HASH_SHA256; | |
1090 | break; | |
1091 | case HASH_SHA384: | |
1092 | hash = TLS_HASH_SHA384; | |
1093 | break; | |
1094 | case HASH_SHA512: | |
1095 | hash = TLS_HASH_SHA512; | |
1096 | break; | |
1097 | default: | |
1098 | continue; | |
1099 | } | |
4254257f | 1100 | if (this->rsa) |
d29a82a9 | 1101 | { |
4254257f MW |
1102 | supported->write_uint8(supported, hash); |
1103 | supported->write_uint8(supported, TLS_SIG_RSA); | |
1104 | } | |
1105 | if (this->ecdsa && alg != HASH_MD5 && alg != HASH_SHA224) | |
1106 | { /* currently we have no signature scheme for MD5/SHA224 */ | |
d29a82a9 MW |
1107 | supported->write_uint8(supported, hash); |
1108 | supported->write_uint8(supported, TLS_SIG_ECDSA); | |
1109 | } | |
1110 | } | |
1111 | enumerator->destroy(enumerator); | |
1112 | ||
1113 | writer->write_data16(writer, supported->get_buf(supported)); | |
1114 | supported->destroy(supported); | |
1115 | } | |
1116 | ||
3f7bb88b MW |
1117 | /** |
1118 | * Mapping groups to TLS named curves | |
1119 | */ | |
1120 | static struct { | |
1121 | diffie_hellman_group_t group; | |
1122 | tls_named_curve_t curve; | |
1123 | } curves[] = { | |
1124 | { ECP_256_BIT, TLS_SECP256R1}, | |
1125 | { ECP_384_BIT, TLS_SECP384R1}, | |
1126 | { ECP_521_BIT, TLS_SECP521R1}, | |
1127 | { ECP_224_BIT, TLS_SECP224R1}, | |
1128 | { ECP_192_BIT, TLS_SECP192R1}, | |
1129 | }; | |
1130 | ||
1131 | /** | |
1132 | * Filter EC groups, add TLS curve | |
1133 | */ | |
1134 | static bool group_filter(void *null, | |
1135 | diffie_hellman_group_t *in, diffie_hellman_group_t *out, | |
1136 | void* dummy1, tls_named_curve_t *curve) | |
1137 | { | |
1138 | int i; | |
1139 | ||
1140 | for (i = 0; i < countof(curves); i++) | |
1141 | { | |
1142 | if (curves[i].group == *in) | |
1143 | { | |
1144 | if (out) | |
1145 | { | |
1146 | *out = curves[i].group; | |
1147 | } | |
1148 | if (curve) | |
1149 | { | |
1150 | *curve = curves[i].curve; | |
1151 | } | |
1152 | return TRUE; | |
1153 | } | |
1154 | } | |
1155 | return FALSE; | |
1156 | } | |
1157 | ||
1158 | METHOD(tls_crypto_t, create_ec_enumerator, enumerator_t*, | |
1159 | private_tls_crypto_t *this) | |
37a59a8f | 1160 | { |
3f7bb88b MW |
1161 | return enumerator_create_filter( |
1162 | lib->crypto->create_dh_enumerator(lib->crypto), | |
1163 | (void*)group_filter, NULL, NULL); | |
37a59a8f MW |
1164 | } |
1165 | ||
dc9f34be MW |
1166 | METHOD(tls_crypto_t, set_protection, void, |
1167 | private_tls_crypto_t *this, tls_protection_t *protection) | |
1168 | { | |
1169 | this->protection = protection; | |
1170 | } | |
1171 | ||
84d67ead MW |
1172 | METHOD(tls_crypto_t, append_handshake, void, |
1173 | private_tls_crypto_t *this, tls_handshake_type_t type, chunk_t data) | |
1174 | { | |
1175 | u_int32_t header; | |
1176 | ||
1177 | /* reconstruct handshake header */ | |
1178 | header = htonl(data.len | (type << 24)); | |
1179 | this->handshake = chunk_cat("mcc", this->handshake, | |
1180 | chunk_from_thing(header), data); | |
1181 | } | |
1182 | ||
1183 | /** | |
d29a82a9 | 1184 | * Create a hash using the suites HASH algorithm |
84d67ead | 1185 | */ |
d29a82a9 | 1186 | static bool hash_data(private_tls_crypto_t *this, chunk_t data, chunk_t *hash) |
84d67ead MW |
1187 | { |
1188 | if (this->tls->get_version(this->tls) >= TLS_1_2) | |
1189 | { | |
1190 | hasher_t *hasher; | |
1191 | suite_algs_t *alg; | |
1192 | ||
1193 | alg = find_suite(this->suite); | |
1194 | if (!alg) | |
1195 | { | |
1196 | return FALSE; | |
1197 | } | |
1198 | hasher = lib->crypto->create_hasher(lib->crypto, alg->hash); | |
1199 | if (!hasher) | |
1200 | { | |
3c19b346 | 1201 | DBG1(DBG_TLS, "%N not supported", hash_algorithm_names, alg->hash); |
84d67ead MW |
1202 | return FALSE; |
1203 | } | |
d29a82a9 | 1204 | hasher->allocate_hash(hasher, data, hash); |
84d67ead MW |
1205 | hasher->destroy(hasher); |
1206 | } | |
1207 | else | |
1208 | { | |
1209 | hasher_t *md5, *sha1; | |
1210 | char buf[HASH_SIZE_MD5 + HASH_SIZE_SHA1]; | |
1211 | ||
1212 | md5 = lib->crypto->create_hasher(lib->crypto, HASH_MD5); | |
1213 | if (!md5) | |
1214 | { | |
3c19b346 | 1215 | DBG1(DBG_TLS, "%N not supported", hash_algorithm_names, HASH_MD5); |
84d67ead MW |
1216 | return FALSE; |
1217 | } | |
d29a82a9 | 1218 | md5->get_hash(md5, data, buf); |
84d67ead MW |
1219 | md5->destroy(md5); |
1220 | sha1 = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); | |
1221 | if (!sha1) | |
1222 | { | |
3c19b346 | 1223 | DBG1(DBG_TLS, "%N not supported", hash_algorithm_names, HASH_SHA1); |
84d67ead MW |
1224 | return FALSE; |
1225 | } | |
d29a82a9 | 1226 | sha1->get_hash(sha1, data, buf + HASH_SIZE_MD5); |
84d67ead MW |
1227 | sha1->destroy(sha1); |
1228 | ||
1229 | *hash = chunk_clone(chunk_from_thing(buf)); | |
1230 | } | |
1231 | return TRUE; | |
1232 | } | |
1233 | ||
dbb7c030 MW |
1234 | /** |
1235 | * Get the signature scheme from a TLS 1.2 hash/sig algorithm pair | |
1236 | */ | |
1237 | static signature_scheme_t hashsig_to_scheme(key_type_t type, | |
1238 | tls_hash_algorithm_t hash, tls_signature_algorithm_t sig) | |
84d67ead | 1239 | { |
dbb7c030 MW |
1240 | switch (sig) |
1241 | { | |
1242 | case TLS_SIG_RSA: | |
1243 | if (type != KEY_RSA) | |
1244 | { | |
1245 | return SIGN_UNKNOWN; | |
1246 | } | |
1247 | switch (hash) | |
1248 | { | |
1249 | case TLS_HASH_MD5: | |
1250 | return SIGN_RSA_EMSA_PKCS1_MD5; | |
1251 | case TLS_HASH_SHA1: | |
1252 | return SIGN_RSA_EMSA_PKCS1_SHA1; | |
1253 | case TLS_HASH_SHA224: | |
1254 | return SIGN_RSA_EMSA_PKCS1_SHA224; | |
1255 | case TLS_HASH_SHA256: | |
1256 | return SIGN_RSA_EMSA_PKCS1_SHA256; | |
1257 | case TLS_HASH_SHA384: | |
1258 | return SIGN_RSA_EMSA_PKCS1_SHA384; | |
1259 | case TLS_HASH_SHA512: | |
1260 | return SIGN_RSA_EMSA_PKCS1_SHA512; | |
1261 | default: | |
1262 | return SIGN_UNKNOWN; | |
1263 | } | |
1264 | case TLS_SIG_ECDSA: | |
1265 | if (type != KEY_ECDSA) | |
1266 | { | |
1267 | return SIGN_UNKNOWN; | |
1268 | } | |
1269 | switch (hash) | |
1270 | { | |
1271 | case TLS_HASH_SHA224: | |
1272 | return SIGN_ECDSA_WITH_SHA1_DER; | |
1273 | case TLS_HASH_SHA256: | |
1274 | return SIGN_ECDSA_WITH_SHA256_DER; | |
1275 | case TLS_HASH_SHA384: | |
1276 | return SIGN_ECDSA_WITH_SHA384_DER; | |
1277 | case TLS_HASH_SHA512: | |
1278 | return SIGN_ECDSA_WITH_SHA512_DER; | |
1279 | default: | |
1280 | return SIGN_UNKNOWN; | |
1281 | } | |
1282 | default: | |
1283 | return SIGN_UNKNOWN; | |
1284 | } | |
1285 | } | |
400df4ca | 1286 | |
d29a82a9 | 1287 | METHOD(tls_crypto_t, sign, bool, |
7e432eff | 1288 | private_tls_crypto_t *this, private_key_t *key, bio_writer_t *writer, |
d29a82a9 | 1289 | chunk_t data, chunk_t hashsig) |
dbb7c030 | 1290 | { |
84d67ead MW |
1291 | if (this->tls->get_version(this->tls) >= TLS_1_2) |
1292 | { | |
dbb7c030 | 1293 | signature_scheme_t scheme; |
7e432eff | 1294 | bio_reader_t *reader; |
dbb7c030 MW |
1295 | u_int8_t hash, alg; |
1296 | chunk_t sig; | |
1297 | bool done = FALSE; | |
1298 | ||
d29a82a9 MW |
1299 | if (!hashsig.len) |
1300 | { /* fallback if none given */ | |
1301 | hashsig = chunk_from_chars( | |
1302 | TLS_HASH_SHA1, TLS_SIG_RSA, TLS_HASH_SHA1, TLS_SIG_ECDSA); | |
1303 | } | |
7e432eff | 1304 | reader = bio_reader_create(hashsig); |
dbb7c030 | 1305 | while (reader->remaining(reader) >= 2) |
400df4ca | 1306 | { |
dbb7c030 MW |
1307 | if (reader->read_uint8(reader, &hash) && |
1308 | reader->read_uint8(reader, &alg)) | |
1309 | { | |
1310 | scheme = hashsig_to_scheme(key->get_type(key), hash, alg); | |
1311 | if (scheme != SIGN_UNKNOWN && | |
d29a82a9 | 1312 | key->sign(key, scheme, data, &sig)) |
dbb7c030 MW |
1313 | { |
1314 | done = TRUE; | |
1315 | break; | |
1316 | } | |
1317 | } | |
1318 | } | |
1319 | reader->destroy(reader); | |
1320 | if (!done) | |
1321 | { | |
1322 | DBG1(DBG_TLS, "none of the proposed hash/sig algorithms supported"); | |
400df4ca MW |
1323 | return FALSE; |
1324 | } | |
d29a82a9 | 1325 | DBG2(DBG_TLS, "created signature with %N/%N", |
dbb7c030 MW |
1326 | tls_hash_algorithm_names, hash, tls_signature_algorithm_names, alg); |
1327 | writer->write_uint8(writer, hash); | |
1328 | writer->write_uint8(writer, alg); | |
400df4ca MW |
1329 | writer->write_data16(writer, sig); |
1330 | free(sig.ptr); | |
1331 | } | |
1332 | else | |
1333 | { | |
dbb7c030 | 1334 | chunk_t sig, hash; |
d29a82a9 | 1335 | bool done; |
dbb7c030 MW |
1336 | |
1337 | switch (key->get_type(key)) | |
400df4ca | 1338 | { |
dbb7c030 | 1339 | case KEY_RSA: |
d29a82a9 | 1340 | if (!hash_data(this, data, &hash)) |
dbb7c030 MW |
1341 | { |
1342 | return FALSE; | |
1343 | } | |
d29a82a9 MW |
1344 | done = key->sign(key, SIGN_RSA_EMSA_PKCS1_NULL, hash, &sig); |
1345 | free(hash.ptr); | |
1346 | if (!done) | |
dbb7c030 | 1347 | { |
dbb7c030 MW |
1348 | return FALSE; |
1349 | } | |
d29a82a9 | 1350 | DBG2(DBG_TLS, "created signature with MD5+SHA1/RSA"); |
dbb7c030 MW |
1351 | break; |
1352 | case KEY_ECDSA: | |
d29a82a9 | 1353 | if (!key->sign(key, SIGN_ECDSA_WITH_SHA1_DER, data, &sig)) |
dbb7c030 MW |
1354 | { |
1355 | return FALSE; | |
1356 | } | |
d29a82a9 | 1357 | DBG2(DBG_TLS, "created signature with SHA1/ECDSA"); |
dbb7c030 MW |
1358 | break; |
1359 | default: | |
1360 | return FALSE; | |
400df4ca MW |
1361 | } |
1362 | writer->write_data16(writer, sig); | |
400df4ca MW |
1363 | free(sig.ptr); |
1364 | } | |
1365 | return TRUE; | |
1366 | } | |
1367 | ||
d29a82a9 | 1368 | METHOD(tls_crypto_t, verify, bool, |
7e432eff | 1369 | private_tls_crypto_t *this, public_key_t *key, bio_reader_t *reader, |
d29a82a9 | 1370 | chunk_t data) |
400df4ca MW |
1371 | { |
1372 | if (this->tls->get_version(this->tls) >= TLS_1_2) | |
1373 | { | |
dbb7c030 | 1374 | signature_scheme_t scheme = SIGN_UNKNOWN; |
400df4ca MW |
1375 | u_int8_t hash, alg; |
1376 | chunk_t sig; | |
84d67ead | 1377 | |
400df4ca MW |
1378 | if (!reader->read_uint8(reader, &hash) || |
1379 | !reader->read_uint8(reader, &alg) || | |
1380 | !reader->read_data16(reader, &sig)) | |
1381 | { | |
d29a82a9 | 1382 | DBG1(DBG_TLS, "received invalid signature"); |
400df4ca MW |
1383 | return FALSE; |
1384 | } | |
dbb7c030 MW |
1385 | scheme = hashsig_to_scheme(key->get_type(key), hash, alg); |
1386 | if (scheme == SIGN_UNKNOWN) | |
84d67ead | 1387 | { |
d29a82a9 | 1388 | DBG1(DBG_TLS, "signature algorithms %N/%N not supported", |
dbb7c030 MW |
1389 | tls_hash_algorithm_names, hash, |
1390 | tls_signature_algorithm_names, alg); | |
84d67ead MW |
1391 | return FALSE; |
1392 | } | |
d29a82a9 | 1393 | if (!key->verify(key, scheme, data, sig)) |
dbb7c030 MW |
1394 | { |
1395 | return FALSE; | |
1396 | } | |
d29a82a9 | 1397 | DBG2(DBG_TLS, "verified signature with %N/%N", |
dbb7c030 | 1398 | tls_hash_algorithm_names, hash, tls_signature_algorithm_names, alg); |
84d67ead MW |
1399 | } |
1400 | else | |
1401 | { | |
400df4ca | 1402 | chunk_t sig, hash; |
d29a82a9 | 1403 | bool done; |
84d67ead | 1404 | |
400df4ca MW |
1405 | if (!reader->read_data16(reader, &sig)) |
1406 | { | |
d29a82a9 | 1407 | DBG1(DBG_TLS, "received invalid signature"); |
400df4ca MW |
1408 | return FALSE; |
1409 | } | |
dbb7c030 | 1410 | switch (key->get_type(key)) |
84d67ead | 1411 | { |
dbb7c030 | 1412 | case KEY_RSA: |
d29a82a9 | 1413 | if (!hash_data(this, data, &hash)) |
dbb7c030 MW |
1414 | { |
1415 | return FALSE; | |
1416 | } | |
d29a82a9 MW |
1417 | done = key->verify(key, SIGN_RSA_EMSA_PKCS1_NULL, hash, sig); |
1418 | free(hash.ptr); | |
1419 | if (!done) | |
dbb7c030 | 1420 | { |
dbb7c030 MW |
1421 | return FALSE; |
1422 | } | |
d29a82a9 | 1423 | DBG2(DBG_TLS, "verified signature data with MD5+SHA1/RSA"); |
dbb7c030 MW |
1424 | break; |
1425 | case KEY_ECDSA: | |
d29a82a9 | 1426 | if (!key->verify(key, SIGN_ECDSA_WITH_SHA1_DER, data, sig)) |
dbb7c030 | 1427 | { |
dbb7c030 MW |
1428 | return FALSE; |
1429 | } | |
d29a82a9 | 1430 | DBG2(DBG_TLS, "verified signature with SHA1/ECDSA"); |
dbb7c030 MW |
1431 | break; |
1432 | default: | |
1433 | return FALSE; | |
84d67ead | 1434 | } |
84d67ead MW |
1435 | } |
1436 | return TRUE; | |
1437 | } | |
1438 | ||
d29a82a9 | 1439 | METHOD(tls_crypto_t, sign_handshake, bool, |
7e432eff | 1440 | private_tls_crypto_t *this, private_key_t *key, bio_writer_t *writer, |
d29a82a9 MW |
1441 | chunk_t hashsig) |
1442 | { | |
1443 | return sign(this, key, writer, this->handshake, hashsig); | |
1444 | } | |
1445 | ||
1446 | METHOD(tls_crypto_t, verify_handshake, bool, | |
7e432eff | 1447 | private_tls_crypto_t *this, public_key_t *key, bio_reader_t *reader) |
d29a82a9 MW |
1448 | { |
1449 | return verify(this, key, reader, this->handshake); | |
1450 | } | |
1451 | ||
84d67ead MW |
1452 | METHOD(tls_crypto_t, calculate_finished, bool, |
1453 | private_tls_crypto_t *this, char *label, char out[12]) | |
1454 | { | |
1455 | chunk_t seed; | |
1456 | ||
1457 | if (!this->prf) | |
1458 | { | |
1459 | return FALSE; | |
1460 | } | |
d29a82a9 | 1461 | if (!hash_data(this, this->handshake, &seed)) |
84d67ead MW |
1462 | { |
1463 | return FALSE; | |
1464 | } | |
97b30b93 MW |
1465 | if (!this->prf->get_bytes(this->prf, label, seed, 12, out)) |
1466 | { | |
1467 | free(seed.ptr); | |
1468 | return FALSE; | |
1469 | } | |
84d67ead MW |
1470 | free(seed.ptr); |
1471 | return TRUE; | |
1472 | } | |
1473 | ||
6a5c86b7 MW |
1474 | /** |
1475 | * Derive master secret from premaster, optionally save session | |
1476 | */ | |
97b30b93 | 1477 | static bool derive_master(private_tls_crypto_t *this, chunk_t premaster, |
6a5c86b7 MW |
1478 | chunk_t session, identification_t *id, |
1479 | chunk_t client_random, chunk_t server_random) | |
18010de2 | 1480 | { |
84543e6e | 1481 | char master[48]; |
6a5c86b7 | 1482 | chunk_t seed; |
84543e6e MW |
1483 | |
1484 | /* derive master secret */ | |
1485 | seed = chunk_cata("cc", client_random, server_random); | |
e7d98b8c MW |
1486 | |
1487 | if (!this->prf->set_key(this->prf, premaster) || | |
1488 | !this->prf->get_bytes(this->prf, "master secret", seed, | |
1489 | sizeof(master), master) || | |
1490 | !this->prf->set_key(this->prf, chunk_from_thing(master))) | |
97b30b93 MW |
1491 | { |
1492 | return FALSE; | |
1493 | } | |
97b30b93 | 1494 | |
6a5c86b7 MW |
1495 | if (this->cache && session.len) |
1496 | { | |
1497 | this->cache->create(this->cache, session, id, chunk_from_thing(master), | |
1498 | this->suite); | |
1499 | } | |
1500 | memwipe(master, sizeof(master)); | |
97b30b93 | 1501 | return TRUE; |
6a5c86b7 MW |
1502 | } |
1503 | ||
1504 | /** | |
1505 | * Expand key material from master secret | |
1506 | */ | |
9020f7d0 | 1507 | static bool expand_keys(private_tls_crypto_t *this, |
6a5c86b7 MW |
1508 | chunk_t client_random, chunk_t server_random) |
1509 | { | |
1510 | chunk_t seed, block, client_write, server_write; | |
1511 | int mks, eks = 0, ivs = 0; | |
84543e6e MW |
1512 | |
1513 | /* derive key block for key expansion */ | |
1514 | mks = this->signer_out->get_key_size(this->signer_out); | |
1515 | if (this->crypter_out) | |
18010de2 | 1516 | { |
84543e6e | 1517 | eks = this->crypter_out->get_key_size(this->crypter_out); |
f139b578 | 1518 | if (this->tls->get_version(this->tls) < TLS_1_1) |
18010de2 | 1519 | { |
3102d866 | 1520 | ivs = this->crypter_out->get_iv_size(this->crypter_out); |
84543e6e MW |
1521 | } |
1522 | } | |
1523 | seed = chunk_cata("cc", server_random, client_random); | |
1524 | block = chunk_alloca((mks + eks + ivs) * 2); | |
97b30b93 MW |
1525 | if (!this->prf->get_bytes(this->prf, "key expansion", seed, |
1526 | block.len, block.ptr)) | |
1527 | { | |
1528 | return FALSE; | |
1529 | } | |
84543e6e MW |
1530 | |
1531 | /* signer keys */ | |
1532 | client_write = chunk_create(block.ptr, mks); | |
1533 | block = chunk_skip(block, mks); | |
1534 | server_write = chunk_create(block.ptr, mks); | |
1535 | block = chunk_skip(block, mks); | |
1536 | if (this->tls->is_server(this->tls)) | |
1537 | { | |
2d56575d MW |
1538 | if (!this->signer_in->set_key(this->signer_in, client_write) || |
1539 | !this->signer_out->set_key(this->signer_out, server_write)) | |
1540 | { | |
1541 | return FALSE; | |
1542 | } | |
84543e6e MW |
1543 | } |
1544 | else | |
1545 | { | |
2d56575d MW |
1546 | if (!this->signer_out->set_key(this->signer_out, client_write) || |
1547 | !this->signer_in->set_key(this->signer_in, server_write)) | |
1548 | { | |
1549 | return FALSE; | |
1550 | } | |
84543e6e MW |
1551 | } |
1552 | ||
1553 | /* crypter keys, and IVs if < TLSv1.2 */ | |
1554 | if (this->crypter_out && this->crypter_in) | |
1555 | { | |
1556 | client_write = chunk_create(block.ptr, eks); | |
1557 | block = chunk_skip(block, eks); | |
1558 | server_write = chunk_create(block.ptr, eks); | |
1559 | block = chunk_skip(block, eks); | |
1560 | ||
1561 | if (this->tls->is_server(this->tls)) | |
1562 | { | |
ce73fc19 MW |
1563 | if (!this->crypter_in->set_key(this->crypter_in, client_write) || |
1564 | !this->crypter_out->set_key(this->crypter_out, server_write)) | |
1565 | { | |
1566 | return FALSE; | |
1567 | } | |
18010de2 MW |
1568 | } |
1569 | else | |
1570 | { | |
ce73fc19 MW |
1571 | if (!this->crypter_out->set_key(this->crypter_out, client_write) || |
1572 | !this->crypter_in->set_key(this->crypter_in, server_write)) | |
1573 | { | |
1574 | return FALSE; | |
1575 | } | |
84543e6e MW |
1576 | } |
1577 | if (ivs) | |
1578 | { | |
1579 | client_write = chunk_create(block.ptr, ivs); | |
1580 | block = chunk_skip(block, ivs); | |
1581 | server_write = chunk_create(block.ptr, ivs); | |
1582 | block = chunk_skip(block, ivs); | |
1583 | ||
1584 | if (this->tls->is_server(this->tls)) | |
18010de2 | 1585 | { |
84543e6e MW |
1586 | this->iv_in = chunk_clone(client_write); |
1587 | this->iv_out = chunk_clone(server_write); | |
1588 | } | |
1589 | else | |
1590 | { | |
1591 | this->iv_out = chunk_clone(client_write); | |
1592 | this->iv_in = chunk_clone(server_write); | |
18010de2 | 1593 | } |
536dbc00 MW |
1594 | } |
1595 | } | |
6a5c86b7 MW |
1596 | |
1597 | /* EAP-MSK */ | |
1598 | if (this->msk_label) | |
1599 | { | |
06c15036 | 1600 | seed = chunk_cata("cc", client_random, server_random); |
6a5c86b7 | 1601 | this->msk = chunk_alloc(64); |
97b30b93 MW |
1602 | if (!this->prf->get_bytes(this->prf, this->msk_label, seed, |
1603 | this->msk.len, this->msk.ptr)) | |
1604 | { | |
1605 | return FALSE; | |
1606 | } | |
6a5c86b7 | 1607 | } |
9020f7d0 | 1608 | return TRUE; |
6a5c86b7 MW |
1609 | } |
1610 | ||
9020f7d0 | 1611 | METHOD(tls_crypto_t, derive_secrets, bool, |
6a5c86b7 MW |
1612 | private_tls_crypto_t *this, chunk_t premaster, chunk_t session, |
1613 | identification_t *id, chunk_t client_random, chunk_t server_random) | |
1614 | { | |
97b30b93 MW |
1615 | return derive_master(this, premaster, session, id, |
1616 | client_random, server_random) && | |
1617 | expand_keys(this, client_random, server_random); | |
6a5c86b7 MW |
1618 | } |
1619 | ||
1620 | METHOD(tls_crypto_t, resume_session, tls_cipher_suite_t, | |
1621 | private_tls_crypto_t *this, chunk_t session, identification_t *id, | |
1622 | chunk_t client_random, chunk_t server_random) | |
1623 | { | |
1624 | chunk_t master; | |
1625 | ||
1626 | if (this->cache && session.len) | |
1627 | { | |
1628 | this->suite = this->cache->lookup(this->cache, session, id, &master); | |
1629 | if (this->suite) | |
1630 | { | |
ae10ee6d | 1631 | this->suite = select_cipher_suite(this, &this->suite, 1, KEY_ANY); |
6a5c86b7 MW |
1632 | if (this->suite) |
1633 | { | |
e7d98b8c MW |
1634 | if (!this->prf->set_key(this->prf, master) || |
1635 | !expand_keys(this, client_random, server_random)) | |
9020f7d0 MW |
1636 | { |
1637 | this->suite = 0; | |
1638 | } | |
6a5c86b7 MW |
1639 | } |
1640 | chunk_clear(&master); | |
1641 | } | |
ae10ee6d | 1642 | return this->suite; |
6a5c86b7 | 1643 | } |
ae10ee6d | 1644 | return 0; |
6a5c86b7 MW |
1645 | } |
1646 | ||
1647 | METHOD(tls_crypto_t, get_session, chunk_t, | |
1648 | private_tls_crypto_t *this, identification_t *server) | |
1649 | { | |
1650 | if (this->cache) | |
1651 | { | |
1652 | return this->cache->check(this->cache, server); | |
1653 | } | |
1654 | return chunk_empty; | |
84543e6e | 1655 | } |
18010de2 | 1656 | |
84543e6e MW |
1657 | METHOD(tls_crypto_t, change_cipher, void, |
1658 | private_tls_crypto_t *this, bool inbound) | |
1659 | { | |
dc9f34be | 1660 | if (this->protection) |
84543e6e | 1661 | { |
dc9f34be MW |
1662 | if (inbound) |
1663 | { | |
1664 | this->protection->set_cipher(this->protection, TRUE, | |
1665 | this->signer_in, this->crypter_in, this->iv_in); | |
1666 | } | |
1667 | else | |
1668 | { | |
1669 | this->protection->set_cipher(this->protection, FALSE, | |
1670 | this->signer_out, this->crypter_out, this->iv_out); | |
1671 | } | |
18010de2 | 1672 | } |
536dbc00 MW |
1673 | } |
1674 | ||
51313a39 MW |
1675 | METHOD(tls_crypto_t, get_eap_msk, chunk_t, |
1676 | private_tls_crypto_t *this) | |
1677 | { | |
1678 | return this->msk; | |
1679 | } | |
1680 | ||
536dbc00 MW |
1681 | METHOD(tls_crypto_t, destroy, void, |
1682 | private_tls_crypto_t *this) | |
1683 | { | |
84543e6e MW |
1684 | DESTROY_IF(this->signer_in); |
1685 | DESTROY_IF(this->signer_out); | |
1686 | DESTROY_IF(this->crypter_in); | |
1687 | DESTROY_IF(this->crypter_out); | |
1688 | free(this->iv_in.ptr); | |
1689 | free(this->iv_out.ptr); | |
84d67ead | 1690 | free(this->handshake.ptr); |
51313a39 | 1691 | free(this->msk.ptr); |
18010de2 | 1692 | DESTROY_IF(this->prf); |
84543e6e | 1693 | free(this->suites); |
536dbc00 MW |
1694 | free(this); |
1695 | } | |
1696 | ||
1697 | /** | |
1698 | * See header | |
1699 | */ | |
6a5c86b7 | 1700 | tls_crypto_t *tls_crypto_create(tls_t *tls, tls_cache_t *cache) |
536dbc00 MW |
1701 | { |
1702 | private_tls_crypto_t *this; | |
4254257f MW |
1703 | enumerator_t *enumerator; |
1704 | credential_type_t type; | |
1705 | int subtype; | |
536dbc00 MW |
1706 | |
1707 | INIT(this, | |
1708 | .public = { | |
1709 | .get_cipher_suites = _get_cipher_suites, | |
18010de2 | 1710 | .select_cipher_suite = _select_cipher_suite, |
35d9c15d | 1711 | .get_dh_group = _get_dh_group, |
d29a82a9 | 1712 | .get_signature_algorithms = _get_signature_algorithms, |
3f7bb88b | 1713 | .create_ec_enumerator = _create_ec_enumerator, |
dc9f34be | 1714 | .set_protection = _set_protection, |
84d67ead | 1715 | .append_handshake = _append_handshake, |
d29a82a9 MW |
1716 | .sign = _sign, |
1717 | .verify = _verify, | |
84d67ead | 1718 | .sign_handshake = _sign_handshake, |
400df4ca | 1719 | .verify_handshake = _verify_handshake, |
84d67ead MW |
1720 | .calculate_finished = _calculate_finished, |
1721 | .derive_secrets = _derive_secrets, | |
6a5c86b7 MW |
1722 | .resume_session = _resume_session, |
1723 | .get_session = _get_session, | |
84543e6e | 1724 | .change_cipher = _change_cipher, |
51313a39 | 1725 | .get_eap_msk = _get_eap_msk, |
536dbc00 MW |
1726 | .destroy = _destroy, |
1727 | }, | |
18010de2 | 1728 | .tls = tls, |
6a5c86b7 | 1729 | .cache = cache, |
536dbc00 MW |
1730 | ); |
1731 | ||
4254257f MW |
1732 | enumerator = lib->creds->create_builder_enumerator(lib->creds); |
1733 | while (enumerator->enumerate(enumerator, &type, &subtype)) | |
1734 | { | |
1735 | if (type == CRED_PUBLIC_KEY) | |
1736 | { | |
1737 | switch (subtype) | |
1738 | { | |
1739 | case KEY_RSA: | |
1740 | this->rsa = TRUE; | |
1741 | break; | |
1742 | case KEY_ECDSA: | |
1743 | this->ecdsa = TRUE; | |
1744 | break; | |
1745 | default: | |
1746 | break; | |
1747 | } | |
1748 | } | |
1749 | } | |
1750 | enumerator->destroy(enumerator); | |
1751 | ||
96b2fbcc MW |
1752 | switch (tls->get_purpose(tls)) |
1753 | { | |
1754 | case TLS_PURPOSE_EAP_TLS: | |
1bee89d3 | 1755 | case TLS_PURPOSE_EAP_PEAP: |
96b2fbcc MW |
1756 | /* MSK PRF ASCII constant label according to EAP-TLS RFC 5216 */ |
1757 | this->msk_label = "client EAP encryption"; | |
1758 | build_cipher_suite_list(this, FALSE); | |
1759 | break; | |
1760 | case TLS_PURPOSE_EAP_TTLS: | |
1761 | /* MSK PRF ASCII constant label according to EAP-TTLS RFC 5281 */ | |
1762 | this->msk_label = "ttls keying material"; | |
1763 | build_cipher_suite_list(this, TRUE); | |
1764 | break; | |
bda7d9d9 | 1765 | case TLS_PURPOSE_GENERIC: |
bda7d9d9 MW |
1766 | build_cipher_suite_list(this, TRUE); |
1767 | break; | |
99b0f633 AS |
1768 | default: |
1769 | break; | |
96b2fbcc | 1770 | } |
536dbc00 MW |
1771 | return &this->public; |
1772 | } |