]>
Commit | Line | Data |
---|---|---|
536dbc00 | 1 | /* |
53ba0801 | 2 | * Copyright (C) 2020 Tobias Brunner |
e5b65657 | 3 | * Copyright (C) 2020-2021 Pascal Knecht |
53ba0801 | 4 | * Copyright (C) 2020 Méline Sieber |
48d6b57c | 5 | * Copyright (C) 2010-2014 Martin Willi |
19ef2aec TB |
6 | * |
7 | * Copyright (C) secunet Security Networks AG | |
536dbc00 MW |
8 | * |
9 | * This program is free software; you can redistribute it and/or modify it | |
10 | * under the terms of the GNU General Public License as published by the | |
11 | * Free Software Foundation; either version 2 of the License, or (at your | |
12 | * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. | |
13 | * | |
14 | * This program is distributed in the hope that it will be useful, but | |
15 | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | |
16 | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
17 | * for more details. | |
18 | */ | |
19 | ||
20 | #include "tls_crypto.h" | |
7a2b0266 | 21 | #include "tls_hkdf.h" |
536dbc00 | 22 | |
f05b4272 | 23 | #include <utils/debug.h> |
48d6b57c | 24 | #include <plugins/plugin_feature.h> |
9803fb82 | 25 | #include <collections/hashtable.h> |
d8e42a3d | 26 | #include <collections/array.h> |
18010de2 | 27 | |
4657b3a4 AS |
28 | ENUM_BEGIN(tls_cipher_suite_names, TLS_NULL_WITH_NULL_NULL, |
29 | TLS_DH_anon_WITH_3DES_EDE_CBC_SHA, | |
30 | "TLS_NULL_WITH_NULL_NULL", | |
31 | "TLS_RSA_WITH_NULL_MD5", | |
32 | "TLS_RSA_WITH_NULL_SHA", | |
33 | "TLS_RSA_EXPORT_WITH_RC4_40_MD5", | |
34 | "TLS_RSA_WITH_RC4_128_MD5", | |
35 | "TLS_RSA_WITH_RC4_128_SHA", | |
36 | "TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5", | |
37 | "TLS_RSA_WITH_IDEA_CBC_SHA", | |
38 | "TLS_RSA_EXPORT_WITH_DES40_CBC_SHA", | |
39 | "TLS_RSA_WITH_DES_CBC_SHA", | |
40 | "TLS_RSA_WITH_3DES_EDE_CBC_SHA", | |
41 | "TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA", | |
42 | "TLS_DH_DSS_WITH_DES_CBC_SHA", | |
43 | "TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA", | |
44 | "TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA", | |
45 | "TLS_DH_RSA_WITH_DES_CBC_SHA", | |
46 | "TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA", | |
47 | "TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", | |
37d2d7e1 | 48 | "TLS_DHE_DSS_WITH_DES_CBC_SHA", |
4657b3a4 AS |
49 | "TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA", |
50 | "TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", | |
51 | "TLS_DHE_RSA_WITH_DES_CBC_SHA", | |
52 | "TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA", | |
53 | "TLS_DH_anon_EXPORT_WITH_RC4_40_MD5", | |
54 | "TLS_DH_anon_WITH_RC4_128_MD5", | |
55 | "TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA", | |
56 | "TLS_DH_anon_WITH_DES_CBC_SHA", | |
57 | "TLS_DH_anon_WITH_3DES_EDE_CBC_SHA"); | |
58 | ENUM_NEXT(tls_cipher_suite_names, TLS_KRB5_WITH_DES_CBC_SHA, | |
59 | TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA, | |
60 | TLS_DH_anon_WITH_3DES_EDE_CBC_SHA, | |
61 | "TLS_KRB5_WITH_DES_CBC_SHA", | |
62 | "TLS_KRB5_WITH_3DES_EDE_CBC_SHA", | |
63 | "TLS_KRB5_WITH_RC4_128_SHA", | |
64 | "TLS_KRB5_WITH_IDEA_CBC_SHA", | |
65 | "TLS_KRB5_WITH_DES_CBC_MD5", | |
66 | "TLS_KRB5_WITH_3DES_EDE_CBC_MD5", | |
67 | "TLS_KRB5_WITH_RC4_128_MD5", | |
68 | "TLS_KRB5_WITH_IDEA_CBC_MD5", | |
69 | "TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA", | |
37d2d7e1 | 70 | "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA", |
4657b3a4 AS |
71 | "TLS_KRB5_EXPORT_WITH_RC4_40_SHA", |
72 | "TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5", | |
73 | "TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5", | |
74 | "TLS_KRB5_EXPORT_WITH_RC4_40_MD5", | |
75 | "TLS_PSK_WITH_NULL_SHA", | |
76 | "TLS_DHE_PSK_WITH_NULL_SHA", | |
77 | "TLS_RSA_PSK_WITH_NULL_SHA", | |
78 | "TLS_RSA_WITH_AES_128_CBC_SHA", | |
79 | "TLS_DH_DSS_WITH_AES_128_CBC_SHA", | |
80 | "TLS_DH_RSA_WITH_AES_128_CBC_SHA", | |
81 | "TLS_DHE_DSS_WITH_AES_128_CBC_SHA", | |
82 | "TLS_DHE_RSA_WITH_AES_128_CBC_SHA", | |
83 | "TLS_DH_anon_WITH_AES_128_CBC_SHA", | |
84 | "TLS_RSA_WITH_AES_256_CBC_SHA", | |
85 | "TLS_DH_DSS_WITH_AES_256_CBC_SHA", | |
86 | "TLS_DH_RSA_WITH_AES_256_CBC_SHA", | |
87 | "TLS_DHE_DSS_WITH_AES_256_CBC_SHA", | |
88 | "TLS_DHE_RSA_WITH_AES_256_CBC_SHA", | |
89 | "TLS_DH_anon_WITH_AES_256_CBC_SHA", | |
90 | "TLS_RSA_WITH_NULL_SHA256", | |
e67e8dd1 | 91 | "TLS_RSA_WITH_AES_128_CBC_SHA256", |
4657b3a4 AS |
92 | "TLS_RSA_WITH_AES_256_CBC_SHA256", |
93 | "TLS_DH_DSS_WITH_AES_128_CBC_SHA256", | |
94 | "TLS_DH_RSA_WITH_AES_128_CBC_SHA256", | |
95 | "TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", | |
96 | "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA", | |
97 | "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA", | |
98 | "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA", | |
99 | "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA", | |
37d2d7e1 | 100 | "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA", |
4657b3a4 AS |
101 | "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA"); |
102 | ENUM_NEXT(tls_cipher_suite_names, TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, | |
103 | TLS_DH_anon_WITH_AES_256_CBC_SHA256, | |
104 | TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA, | |
105 | "TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", | |
106 | "TLS_DH_DSS_WITH_AES_256_CBC_SHA256", | |
107 | "TLS_DH_RSA_WITH_AES_256_CBC_SHA256", | |
108 | "TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", | |
109 | "TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", | |
110 | "TLS_DH_anon_WITH_AES_128_CBC_SHA256", | |
111 | "TLS_DH_anon_WITH_AES_256_CBC_SHA256"); | |
112 | ENUM_NEXT(tls_cipher_suite_names, TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, | |
37d2d7e1 | 113 | TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256, |
4657b3a4 AS |
114 | TLS_DH_anon_WITH_AES_256_CBC_SHA256, |
115 | "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA", | |
116 | "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA", | |
117 | "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA", | |
118 | "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA", | |
119 | "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA", | |
120 | "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA", | |
121 | "TLS_PSK_WITH_RC4_128_SHA", | |
e67e8dd1 | 122 | "TLS_PSK_WITH_3DES_EDE_CBC_SHA", |
4657b3a4 AS |
123 | "TLS_PSK_WITH_AES_128_CBC_SHA", |
124 | "TLS_PSK_WITH_AES_256_CBC_SHA", | |
125 | "TLS_DHE_PSK_WITH_RC4_128_SHA", | |
126 | "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA", | |
127 | "TLS_DHE_PSK_WITH_AES_128_CBC_SHA", | |
e67e8dd1 | 128 | "TLS_DHE_PSK_WITH_AES_256_CBC_SHA", |
4657b3a4 AS |
129 | "TLS_RSA_PSK_WITH_RC4_128_SHA", |
130 | "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA", | |
131 | "TLS_RSA_PSK_WITH_AES_128_CBC_SHA", | |
132 | "TLS_RSA_PSK_WITH_AES_256_CBC_SHA", | |
133 | "TLS_RSA_WITH_SEED_CBC_SHA", | |
134 | "TLS_DH_DSS_WITH_SEED_CBC_SHA", | |
135 | "TLS_DH_RSA_WITH_SEED_CBC_SHA", | |
136 | "TLS_DHE_DSS_WITH_SEED_CBC_SHA", | |
137 | "TLS_DHE_RSA_WITH_SEED_CBC_SHA", | |
138 | "TLS_DH_anon_WITH_SEED_CBC_SHA", | |
139 | "TLS_RSA_WITH_AES_128_GCM_SHA256", | |
140 | "TLS_RSA_WITH_AES_256_GCM_SHA384", | |
141 | "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", | |
142 | "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", | |
143 | "TLS_DH_RSA_WITH_AES_128_GCM_SHA256", | |
144 | "TLS_DH_RSA_WITH_AES_256_GCM_SHA384", | |
145 | "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256", | |
146 | "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384", | |
147 | "TLS_DH_DSS_WITH_AES_128_GCM_SHA256", | |
148 | "TLS_DH_DSS_WITH_AES_256_GCM_SHA384", | |
149 | "TLS_DH_anon_WITH_AES_128_GCM_SHA256", | |
150 | "TLS_DH_anon_WITH_AES_256_GCM_SHA384", | |
151 | "TLS_PSK_WITH_AES_128_GCM_SHA256", | |
152 | "TLS_PSK_WITH_AES_256_GCM_SHA384", | |
153 | "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256", | |
154 | "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384", | |
155 | "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256", | |
156 | "TLS_RSA_PSK_WITH_AES_256_GCM_SHA384", | |
157 | "TLS_PSK_WITH_AES_128_CBC_SHA256", | |
158 | "TLS_PSK_WITH_AES_256_CBC_SHA384", | |
159 | "TLS_PSK_WITH_NULL_SHA256", | |
160 | "TLS_PSK_WITH_NULL_SHA384", | |
161 | "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256", | |
162 | "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384", | |
163 | "TLS_DHE_PSK_WITH_NULL_SHA256", | |
164 | "TLS_DHE_PSK_WITH_NULL_SHA384", | |
165 | "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256", | |
166 | "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384", | |
167 | "TLS_RSA_PSK_WITH_NULL_SHA256", | |
168 | "TLS_RSA_PSK_WITH_NULL_SHA384", | |
169 | "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256", | |
170 | "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256", | |
171 | "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256", | |
172 | "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256", | |
173 | "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256", | |
174 | "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256", | |
175 | "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256", | |
176 | "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256", | |
177 | "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256", | |
178 | "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256", | |
179 | "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256", | |
180 | "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256"); | |
181 | ENUM_NEXT(tls_cipher_suite_names, TLS_EMPTY_RENEGOTIATION_INFO_SCSV, | |
37d2d7e1 | 182 | TLS_EMPTY_RENEGOTIATION_INFO_SCSV, |
4657b3a4 AS |
183 | TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256, |
184 | "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"); | |
7a2b0266 | 185 | ENUM_NEXT(tls_cipher_suite_names, TLS_AES_128_GCM_SHA256, |
186 | TLS_AES_128_CCM_8_SHA256, | |
187 | TLS_EMPTY_RENEGOTIATION_INFO_SCSV, | |
188 | "TLS_AES_128_GCM_SHA256", | |
189 | "TLS_AES_256_GCM_SHA384", | |
190 | "TLS_CHACHA20_POLY1305_SHA256", | |
191 | "TLS_AES_128_CCM_SHA256", | |
192 | "TLS_AES_128_CCM_8_SHA256"); | |
4657b3a4 | 193 | ENUM_NEXT(tls_cipher_suite_names, TLS_ECDH_ECDSA_WITH_NULL_SHA, |
37d2d7e1 | 194 | TLS_ECDHE_PSK_WITH_NULL_SHA384, |
7a2b0266 | 195 | TLS_AES_128_CCM_8_SHA256, |
4657b3a4 AS |
196 | "TLS_ECDH_ECDSA_WITH_NULL_SHA", |
197 | "TLS_ECDH_ECDSA_WITH_RC4_128_SHA", | |
198 | "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA", | |
199 | "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", | |
200 | "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", | |
201 | "TLS_ECDHE_ECDSA_WITH_NULL_SHA", | |
202 | "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", | |
203 | "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", | |
204 | "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", | |
205 | "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", | |
206 | "TLS_ECDH_RSA_WITH_NULL_SHA", | |
207 | "TLS_ECDH_RSA_WITH_RC4_128_SHA", | |
208 | "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA", | |
209 | "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", | |
210 | "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", | |
211 | "TLS_ECDHE_RSA_WITH_NULL_SHA", | |
212 | "TLS_ECDHE_RSA_WITH_RC4_128_SHA", | |
213 | "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", | |
214 | "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", | |
215 | "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", | |
216 | "TLS_ECDH_anon_WITH_NULL_SHA", | |
217 | "TLS_ECDH_anon_WITH_RC4_128_SHA", | |
218 | "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA", | |
219 | "TLS_ECDH_anon_WITH_AES_128_CBC_SHA", | |
220 | "TLS_ECDH_anon_WITH_AES_256_CBC_SHA", | |
221 | "TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA", | |
222 | "TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA", | |
223 | "TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA", | |
224 | "TLS_SRP_SHA_WITH_AES_128_CBC_SHA", | |
225 | "TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA", | |
226 | "TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA", | |
227 | "TLS_SRP_SHA_WITH_AES_256_CBC_SHA", | |
228 | "TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA", | |
229 | "TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA", | |
230 | "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", | |
231 | "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", | |
232 | "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", | |
233 | "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", | |
234 | "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", | |
235 | "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", | |
236 | "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", | |
237 | "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", | |
238 | "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", | |
239 | "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", | |
240 | "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", | |
241 | "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384", | |
242 | "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", | |
243 | "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", | |
244 | "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", | |
245 | "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384", | |
246 | "TLS_ECDHE_PSK_WITH_RC4_128_SHA", | |
247 | "TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA", | |
248 | "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA", | |
249 | "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA", | |
250 | "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256", | |
251 | "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384", | |
252 | "TLS_ECDHE_PSK_WITH_NULL_SHA", | |
253 | "TLS_ECDHE_PSK_WITH_NULL_SHA256", | |
254 | "TLS_ECDHE_PSK_WITH_NULL_SHA384"); | |
f81c04e9 PK |
255 | ENUM_NEXT(tls_cipher_suite_names, TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, |
256 | TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256, | |
257 | TLS_ECDHE_PSK_WITH_NULL_SHA384, | |
258 | "TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", | |
259 | "TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", | |
260 | "TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256"); | |
261 | ENUM_END(tls_cipher_suite_names, TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256); | |
262 | ||
4657b3a4 | 263 | |
9dd2ca92 MW |
264 | ENUM(tls_hash_algorithm_names, TLS_HASH_NONE, TLS_HASH_SHA512, |
265 | "NONE", | |
266 | "MD5", | |
267 | "SHA1", | |
268 | "SHA224", | |
269 | "SHA256", | |
270 | "SHA384", | |
271 | "SHA512", | |
272 | ); | |
273 | ||
1b593e1d TB |
274 | ENUM_BEGIN(tls_signature_scheme_names, |
275 | TLS_SIG_RSA_PKCS1_SHA1, TLS_SIG_RSA_PKCS1_SHA1, | |
276 | "RSA_PKCS1_SHA1"); | |
277 | ENUM_NEXT(tls_signature_scheme_names, | |
278 | TLS_SIG_ECDSA_SHA1, TLS_SIG_ECDSA_SHA1, TLS_SIG_RSA_PKCS1_SHA1, | |
279 | "ECDSA_SHA1"); | |
280 | ENUM_NEXT(tls_signature_scheme_names, | |
91c9e4d5 PK |
281 | TLS_SIG_RSA_PKCS1_SHA224, TLS_SIG_ECDSA_SHA224, TLS_SIG_ECDSA_SHA1, |
282 | "RSA_PKCS1_SHA224", | |
283 | "DSA_SHA224", | |
284 | "ECDSA_SHA224"); | |
1b593e1d | 285 | ENUM_NEXT(tls_signature_scheme_names, |
91c9e4d5 PK |
286 | TLS_SIG_RSA_PKCS1_SHA256, TLS_SIG_ECDSA_SHA256, TLS_SIG_ECDSA_SHA224, |
287 | "RSA_PKCS1_SHA256", | |
288 | "DSA_SHA256", | |
1b593e1d TB |
289 | "ECDSA_SHA256"); |
290 | ENUM_NEXT(tls_signature_scheme_names, | |
91c9e4d5 PK |
291 | TLS_SIG_RSA_PKCS1_SHA384, TLS_SIG_ECDSA_SHA384, TLS_SIG_ECDSA_SHA256, |
292 | "RSA_PKCS1_SHA384", | |
293 | "DSA_SHA384", | |
1b593e1d TB |
294 | "ECDSA_SHA384"); |
295 | ENUM_NEXT(tls_signature_scheme_names, | |
91c9e4d5 PK |
296 | TLS_SIG_RSA_PKCS1_SHA512, TLS_SIG_ECDSA_SHA512, TLS_SIG_ECDSA_SHA384, |
297 | "RSA_PKCS1_SHA512", | |
298 | "DSA_SHA512", | |
1b593e1d TB |
299 | "ECDSA_SHA512"); |
300 | ENUM_NEXT(tls_signature_scheme_names, | |
301 | TLS_SIG_RSA_PSS_RSAE_SHA256, TLS_SIG_RSA_PSS_PSS_SHA512, TLS_SIG_ECDSA_SHA512, | |
302 | "RSA_PSS_RSAE_SHA256", | |
303 | "RSA_PSS_RSAE_SHA384", | |
304 | "RSA_PSS_RSAE_SHA512", | |
305 | "ED25519", | |
306 | "ED448", | |
307 | "RSA_PSS_PSS_SHA256", | |
308 | "RSA_PSS_PSS_SHA384", | |
309 | "RSA_PSS_PSS_SHA512", | |
9dd2ca92 | 310 | ); |
1b593e1d | 311 | ENUM_END(tls_signature_scheme_names, TLS_SIG_RSA_PSS_PSS_SHA512); |
9dd2ca92 | 312 | |
99dcaea9 MW |
313 | ENUM_BEGIN(tls_client_certificate_type_names, |
314 | TLS_RSA_SIGN, TLS_DSS_EPHEMERAL_DH, | |
315 | "RSA_SIGN", | |
316 | "DSA_SIGN", | |
317 | "RSA_FIXED_DH", | |
318 | "DSS_FIXED_DH", | |
319 | "RSA_EPHEMERAL_DH", | |
320 | "DSS_EPHEMERAL_DH"); | |
321 | ENUM_NEXT(tls_client_certificate_type_names, | |
322 | TLS_FORTEZZA_DMS, TLS_FORTEZZA_DMS, TLS_DSS_EPHEMERAL_DH, | |
323 | "FORTEZZA_DMS"); | |
324 | ENUM_NEXT(tls_client_certificate_type_names, | |
325 | TLS_ECDSA_SIGN, TLS_ECDSA_FIXED_ECDH, TLS_FORTEZZA_DMS, | |
326 | "ECDSA_SIGN", | |
327 | "RSA_FIXED_ECDH", | |
328 | "ECDSA_FIXED_ECDH"); | |
329 | ENUM_END(tls_client_certificate_type_names, TLS_ECDSA_FIXED_ECDH); | |
330 | ||
691ca54d MW |
331 | ENUM(tls_ecc_curve_type_names, TLS_ECC_EXPLICIT_PRIME, TLS_ECC_NAMED_CURVE, |
332 | "EXPLICIT_PRIME", | |
333 | "EXPLICIT_CHAR2", | |
334 | "NAMED_CURVE", | |
335 | ); | |
336 | ||
7a2b0266 | 337 | ENUM_BEGIN(tls_named_group_names, TLS_SECT163K1, TLS_SECP521R1, |
691ca54d MW |
338 | "SECT163K1", |
339 | "SECT163R1", | |
340 | "SECT163R2", | |
341 | "SECT193R1", | |
342 | "SECT193R2", | |
343 | "SECT233K1", | |
344 | "SECT233R1", | |
345 | "SECT239K1", | |
346 | "SECT283K1", | |
347 | "SECT283R1", | |
348 | "SECT409K1", | |
349 | "SECT409R1", | |
350 | "SECT571K1", | |
351 | "SECT571R1", | |
352 | "SECP160K1", | |
353 | "SECP160R1", | |
354 | "SECP160R2", | |
355 | "SECP192K1", | |
356 | "SECP192R1", | |
357 | "SECP224K1", | |
358 | "SECP224R1", | |
359 | "SECP256K1", | |
360 | "SECP256R1", | |
361 | "SECP384R1", | |
362 | "SECP521R1", | |
363 | ); | |
3101120c | 364 | ENUM_NEXT(tls_named_group_names, TLS_CURVE25519, TLS_CURVE448, TLS_SECP521R1, |
7a2b0266 | 365 | "CURVE25519", |
366 | "CURVE448", | |
367 | ); | |
3101120c | 368 | ENUM_NEXT(tls_named_group_names, TLS_FFDHE2048, TLS_FFDHE8192, TLS_CURVE448, |
7a2b0266 | 369 | "FFDHE2048", |
370 | "FFDHE3072", | |
371 | "FFDHE4096", | |
372 | "FFDHE6144", | |
373 | "FFDHE8192", | |
374 | ); | |
375 | ENUM_END(tls_named_group_names, TLS_FFDHE8192); | |
691ca54d | 376 | |
ec7d4e70 | 377 | ENUM(tls_ansi_point_format_names, TLS_ANSI_COMPRESSED, TLS_ANSI_HYBRID_Y, |
e6cce7ff MW |
378 | "compressed", |
379 | "compressed y", | |
380 | "uncompressed", | |
381 | "uncompressed y", | |
382 | "hybrid", | |
383 | "hybrid y", | |
384 | ); | |
99dcaea9 | 385 | |
02281c87 MW |
386 | ENUM(tls_ec_point_format_names, |
387 | TLS_EC_POINT_UNCOMPRESSED, TLS_EC_POINT_ANSIX962_COMPRESSED_CHAR2, | |
388 | "uncompressed", | |
389 | "ansiX962 compressed prime", | |
390 | "ansiX962 compressed char2", | |
391 | ); | |
392 | ||
536dbc00 MW |
393 | typedef struct private_tls_crypto_t private_tls_crypto_t; |
394 | ||
395 | /** | |
396 | * Private data of an tls_crypto_t object. | |
397 | */ | |
398 | struct private_tls_crypto_t { | |
399 | ||
400 | /** | |
401 | * Public tls_crypto_t interface. | |
402 | */ | |
403 | tls_crypto_t public; | |
18010de2 | 404 | |
dc9f34be MW |
405 | /** |
406 | * Protection layer | |
407 | */ | |
408 | tls_protection_t *protection; | |
409 | ||
18010de2 MW |
410 | /** |
411 | * List of supported/acceptable cipher suites | |
412 | */ | |
413 | tls_cipher_suite_t *suites; | |
414 | ||
415 | /** | |
416 | * Number of supported suites | |
417 | */ | |
418 | int suite_count; | |
419 | ||
7a2b0266 | 420 | /** |
421 | * HKDF for TLS 1.3 | |
422 | */ | |
423 | tls_hkdf_t *hkdf; | |
424 | ||
18010de2 MW |
425 | /** |
426 | * Selected cipher suite | |
427 | */ | |
428 | tls_cipher_suite_t suite; | |
429 | ||
4254257f MW |
430 | /** |
431 | * RSA supported? | |
432 | */ | |
433 | bool rsa; | |
434 | ||
435 | /** | |
436 | * ECDSA supported? | |
437 | */ | |
438 | bool ecdsa; | |
439 | ||
18010de2 MW |
440 | /** |
441 | * TLS context | |
442 | */ | |
443 | tls_t *tls; | |
444 | ||
6a5c86b7 MW |
445 | /** |
446 | * TLS session cache | |
447 | */ | |
448 | tls_cache_t *cache; | |
449 | ||
84d67ead | 450 | /** |
2db6d5b8 | 451 | * All handshake data concatenated |
84d67ead MW |
452 | */ |
453 | chunk_t handshake; | |
454 | ||
18010de2 MW |
455 | /** |
456 | * Connection state TLS PRF | |
457 | */ | |
458 | tls_prf_t *prf; | |
84543e6e MW |
459 | |
460 | /** | |
d3204677 | 461 | * AEAD transform for inbound traffic |
84543e6e | 462 | */ |
d3204677 | 463 | tls_aead_t *aead_in; |
84543e6e MW |
464 | |
465 | /** | |
d3204677 | 466 | * AEAD transform for outbound traffic |
84543e6e | 467 | */ |
d3204677 | 468 | tls_aead_t *aead_out; |
51313a39 MW |
469 | |
470 | /** | |
a6444fcd | 471 | * EAP-[T]TLS MSK |
51313a39 MW |
472 | */ |
473 | chunk_t msk; | |
a6444fcd AS |
474 | |
475 | /** | |
476 | * ASCII string constant used as seed for EAP-[T]TLS MSK PRF | |
477 | */ | |
478 | char *msk_label; | |
536dbc00 MW |
479 | }; |
480 | ||
84543e6e MW |
481 | typedef struct { |
482 | tls_cipher_suite_t suite; | |
4cdade5a | 483 | key_type_t key; |
3af7c6db | 484 | key_exchange_method_t dh; |
84543e6e MW |
485 | hash_algorithm_t hash; |
486 | pseudo_random_function_t prf; | |
487 | integrity_algorithm_t mac; | |
488 | encryption_algorithm_t encr; | |
489 | size_t encr_size; | |
281766c5 TB |
490 | tls_version_t min_version; |
491 | tls_version_t max_version; | |
84543e6e MW |
492 | } suite_algs_t; |
493 | ||
494 | /** | |
495 | * Mapping suites to a set of algorithms | |
d107198f PK |
496 | * |
497 | * The order represents the descending preference of cipher suites and follows | |
498 | * this rule set: | |
499 | * | |
500 | * 1. TLS 1.3 > Legacy TLS | |
501 | * 2. AES > CAMELLIA > NULL | |
502 | * 3. AES256 > AES128 | |
503 | * 4. GCM > CBC | |
504 | * 5. ECDHE > DHE > NULL | |
505 | * 6. ECDSA > RSA | |
506 | * 7. SHA384 > SHA256 > SHA1 | |
507 | * | |
84543e6e MW |
508 | */ |
509 | static suite_algs_t suite_algs[] = { | |
7a2b0266 | 510 | /* Cipher suites of TLS 1.3: key exchange and authentication |
b7c167f9 | 511 | * delegated to extensions, therefore KEY_ANY, KE_NONE, PRF_UNDEFINED */ |
7a2b0266 | 512 | { TLS_AES_256_GCM_SHA384, |
b7c167f9 | 513 | KEY_ANY, KE_NONE, |
7a2b0266 | 514 | HASH_SHA384, PRF_UNDEFINED, |
515 | AUTH_HMAC_SHA2_384_384, ENCR_AES_GCM_ICV16, 32, | |
281766c5 | 516 | TLS_1_3, TLS_1_3, |
7a2b0266 | 517 | }, |
d107198f | 518 | { TLS_AES_128_GCM_SHA256, |
b7c167f9 | 519 | KEY_ANY, KE_NONE, |
d107198f PK |
520 | HASH_SHA256, PRF_UNDEFINED, |
521 | AUTH_HMAC_SHA2_256_256, ENCR_AES_GCM_ICV16, 16, | |
522 | TLS_1_3, TLS_1_3, | |
523 | }, | |
7a2b0266 | 524 | { TLS_CHACHA20_POLY1305_SHA256, |
b7c167f9 | 525 | KEY_ANY, KE_NONE, |
7a2b0266 | 526 | HASH_SHA256, PRF_UNDEFINED, |
b7ea969b | 527 | AUTH_HMAC_SHA2_256_256, ENCR_CHACHA20_POLY1305, 32, |
281766c5 | 528 | TLS_1_3, TLS_1_3, |
7a2b0266 | 529 | }, |
530 | { TLS_AES_128_CCM_SHA256, | |
b7c167f9 | 531 | KEY_ANY, KE_NONE, |
281766c5 TB |
532 | HASH_SHA256, PRF_UNDEFINED, |
533 | AUTH_HMAC_SHA2_256_256, ENCR_AES_CCM_ICV16, 16, | |
534 | TLS_1_3, TLS_1_3, | |
7a2b0266 | 535 | }, |
536 | { TLS_AES_128_CCM_8_SHA256, | |
b7c167f9 | 537 | KEY_ANY, KE_NONE, |
281766c5 TB |
538 | HASH_SHA256, PRF_UNDEFINED, |
539 | AUTH_HMAC_SHA2_256_256, ENCR_AES_CCM_ICV8, 16, | |
540 | TLS_1_3, TLS_1_3, | |
7a2b0266 | 541 | }, |
542 | /* Legacy TLS cipher suites */ | |
d107198f PK |
543 | { TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, |
544 | KEY_ECDSA, ECP_384_BIT, | |
545 | HASH_SHA384, PRF_HMAC_SHA2_384, | |
546 | AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 32, | |
547 | TLS_1_2, TLS_1_2, | |
2066918d | 548 | }, |
d107198f PK |
549 | { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, |
550 | KEY_ECDSA, ECP_384_BIT, | |
551 | HASH_SHA384, PRF_HMAC_SHA2_384, | |
552 | AUTH_HMAC_SHA2_384_384, ENCR_AES_CBC, 32, | |
281766c5 | 553 | TLS_1_2, TLS_1_2, |
2066918d MW |
554 | }, |
555 | { TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, | |
556 | KEY_ECDSA, ECP_384_BIT, | |
ed57dfca | 557 | HASH_SHA256, PRF_HMAC_SHA2_256, |
7a2b0266 | 558 | AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 32, |
281766c5 | 559 | TLS_1_0, TLS_1_2, |
2066918d | 560 | }, |
d06890d6 MW |
561 | { TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, |
562 | KEY_ECDSA, ECP_256_BIT, | |
563 | HASH_SHA256, PRF_HMAC_SHA2_256, | |
7a2b0266 | 564 | AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 16, |
281766c5 | 565 | TLS_1_2, TLS_1_2, |
d06890d6 | 566 | }, |
d107198f PK |
567 | { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, |
568 | KEY_ECDSA, ECP_256_BIT, | |
569 | HASH_SHA256, PRF_HMAC_SHA2_256, | |
570 | AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 16, | |
281766c5 | 571 | TLS_1_2, TLS_1_2, |
d06890d6 | 572 | }, |
d107198f PK |
573 | { TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, |
574 | KEY_ECDSA, ECP_256_BIT, | |
ed57dfca | 575 | HASH_SHA256, PRF_HMAC_SHA2_256, |
7a2b0266 | 576 | AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 16, |
281766c5 | 577 | TLS_1_0, TLS_1_2, |
2066918d | 578 | }, |
d107198f | 579 | { TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, |
f9c0cf86 | 580 | KEY_RSA, ECP_384_BIT, |
d107198f PK |
581 | HASH_SHA384, PRF_HMAC_SHA2_384, |
582 | AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 32, | |
583 | TLS_1_2, TLS_1_2, | |
2066918d MW |
584 | }, |
585 | { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, | |
f9c0cf86 | 586 | KEY_RSA, ECP_384_BIT, |
2066918d | 587 | HASH_SHA384, PRF_HMAC_SHA2_384, |
7a2b0266 | 588 | AUTH_HMAC_SHA2_384_384, ENCR_AES_CBC, 32, |
281766c5 | 589 | TLS_1_2, TLS_1_2, |
2066918d | 590 | }, |
d107198f PK |
591 | { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, |
592 | KEY_RSA, ECP_384_BIT, | |
593 | HASH_SHA256, PRF_HMAC_SHA2_256, | |
594 | AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 32, | |
595 | TLS_1_0, TLS_1_2, | |
596 | }, | |
d06890d6 MW |
597 | { TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, |
598 | KEY_RSA, ECP_256_BIT, | |
599 | HASH_SHA256, PRF_HMAC_SHA2_256, | |
7a2b0266 | 600 | AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 16, |
281766c5 | 601 | TLS_1_2, TLS_1_2, |
d06890d6 | 602 | }, |
d107198f PK |
603 | { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, |
604 | KEY_RSA, ECP_256_BIT, | |
605 | HASH_SHA256, PRF_HMAC_SHA2_256, | |
606 | AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 16, | |
281766c5 | 607 | TLS_1_2, TLS_1_2, |
d06890d6 | 608 | }, |
d107198f PK |
609 | { TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, |
610 | KEY_RSA, ECP_256_BIT, | |
611 | HASH_SHA256, PRF_HMAC_SHA2_256, | |
7a2b0266 | 612 | AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 16, |
d107198f | 613 | TLS_1_0, TLS_1_2, |
ef0a8e58 | 614 | }, |
d107198f PK |
615 | { TLS_DHE_RSA_WITH_AES_256_GCM_SHA384, |
616 | KEY_RSA, MODP_4096_BIT, | |
617 | HASH_SHA384, PRF_HMAC_SHA2_384, | |
618 | AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 32, | |
619 | TLS_1_2, TLS_1_2, | |
620 | }, | |
621 | { TLS_DHE_RSA_WITH_AES_256_CBC_SHA256, | |
622 | KEY_RSA, MODP_4096_BIT, | |
4cdade5a | 623 | HASH_SHA256, PRF_HMAC_SHA2_256, |
d107198f | 624 | AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 32, |
281766c5 | 625 | TLS_1_2, TLS_1_2, |
ef0a8e58 MW |
626 | }, |
627 | { TLS_DHE_RSA_WITH_AES_256_CBC_SHA, | |
4cdade5a | 628 | KEY_RSA, MODP_3072_BIT, |
ed57dfca | 629 | HASH_SHA256, PRF_HMAC_SHA2_256, |
7a2b0266 | 630 | AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 32, |
281766c5 | 631 | SSL_3_0, TLS_1_2, |
ef0a8e58 | 632 | }, |
d107198f | 633 | { TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256, |
4cdade5a MW |
634 | KEY_RSA, MODP_4096_BIT, |
635 | HASH_SHA256, PRF_HMAC_SHA2_256, | |
d107198f | 636 | AUTH_HMAC_SHA2_256_256, ENCR_CAMELLIA_CBC, 32, |
281766c5 | 637 | TLS_1_2, TLS_1_2, |
ef0a8e58 | 638 | }, |
d107198f PK |
639 | { TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA, |
640 | KEY_RSA, MODP_3072_BIT, | |
641 | HASH_SHA256, PRF_HMAC_SHA2_256, | |
642 | AUTH_HMAC_SHA1_160, ENCR_CAMELLIA_CBC, 32, | |
643 | SSL_3_0, TLS_1_2, | |
644 | }, | |
d06890d6 MW |
645 | { TLS_DHE_RSA_WITH_AES_128_GCM_SHA256, |
646 | KEY_RSA, MODP_3072_BIT, | |
647 | HASH_SHA256, PRF_HMAC_SHA2_256, | |
7a2b0266 | 648 | AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 16, |
281766c5 | 649 | TLS_1_2, TLS_1_2, |
d06890d6 | 650 | }, |
d107198f PK |
651 | { TLS_DHE_RSA_WITH_AES_128_CBC_SHA256, |
652 | KEY_RSA, MODP_3072_BIT, | |
653 | HASH_SHA256, PRF_HMAC_SHA2_256, | |
654 | AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 16, | |
281766c5 | 655 | TLS_1_2, TLS_1_2, |
d06890d6 | 656 | }, |
d107198f | 657 | { TLS_DHE_RSA_WITH_AES_128_CBC_SHA, |
4cdade5a | 658 | KEY_RSA, MODP_2048_BIT, |
d107198f PK |
659 | HASH_SHA256,PRF_HMAC_SHA2_256, |
660 | AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 16, | |
281766c5 | 661 | SSL_3_0, TLS_1_2, |
ef0a8e58 MW |
662 | }, |
663 | { TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256, | |
4cdade5a MW |
664 | KEY_RSA, MODP_3072_BIT, |
665 | HASH_SHA256, PRF_HMAC_SHA2_256, | |
7a2b0266 | 666 | AUTH_HMAC_SHA2_256_256, ENCR_CAMELLIA_CBC, 16, |
281766c5 | 667 | TLS_1_2, TLS_1_2, |
ef0a8e58 | 668 | }, |
d107198f | 669 | { TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA, |
4cdade5a | 670 | KEY_RSA, MODP_2048_BIT, |
ed57dfca | 671 | HASH_SHA256, PRF_HMAC_SHA2_256, |
d107198f | 672 | AUTH_HMAC_SHA1_160, ENCR_CAMELLIA_CBC, 16, |
281766c5 | 673 | SSL_3_0, TLS_1_2, |
ef0a8e58 | 674 | }, |
d107198f | 675 | { TLS_RSA_WITH_AES_256_GCM_SHA384, |
b7c167f9 | 676 | KEY_RSA, KE_NONE, |
d107198f PK |
677 | HASH_SHA384, PRF_HMAC_SHA2_384, |
678 | AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 32, | |
679 | TLS_1_2, TLS_1_2, | |
6e413d9c | 680 | }, |
d107198f | 681 | { TLS_RSA_WITH_AES_256_CBC_SHA256, |
b7c167f9 | 682 | KEY_RSA, KE_NONE, |
4cdade5a | 683 | HASH_SHA256, PRF_HMAC_SHA2_256, |
d107198f | 684 | AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 32, |
281766c5 | 685 | TLS_1_2, TLS_1_2, |
84543e6e MW |
686 | }, |
687 | { TLS_RSA_WITH_AES_256_CBC_SHA, | |
b7c167f9 | 688 | KEY_RSA, KE_NONE, |
ed57dfca | 689 | HASH_SHA256, PRF_HMAC_SHA2_256, |
7a2b0266 | 690 | AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 32, |
281766c5 | 691 | SSL_3_0, TLS_1_2, |
84543e6e | 692 | }, |
d06890d6 | 693 | { TLS_RSA_WITH_AES_128_GCM_SHA256, |
b7c167f9 | 694 | KEY_RSA, KE_NONE, |
d06890d6 | 695 | HASH_SHA256, PRF_HMAC_SHA2_256, |
7a2b0266 | 696 | AUTH_UNDEFINED, ENCR_AES_GCM_ICV16, 16, |
281766c5 | 697 | TLS_1_2, TLS_1_2, |
d06890d6 | 698 | }, |
d107198f | 699 | { TLS_RSA_WITH_AES_128_CBC_SHA256, |
b7c167f9 | 700 | KEY_RSA, KE_NONE, |
d107198f PK |
701 | HASH_SHA256, PRF_HMAC_SHA2_256, |
702 | AUTH_HMAC_SHA2_256_256, ENCR_AES_CBC, 16, | |
281766c5 | 703 | TLS_1_2, TLS_1_2, |
d06890d6 | 704 | }, |
d107198f | 705 | { TLS_RSA_WITH_AES_128_CBC_SHA, |
b7c167f9 | 706 | KEY_RSA, KE_NONE, |
ed57dfca | 707 | HASH_SHA256, PRF_HMAC_SHA2_256, |
d107198f | 708 | AUTH_HMAC_SHA1_160, ENCR_AES_CBC, 16, |
281766c5 | 709 | SSL_3_0, TLS_1_2, |
6e413d9c | 710 | }, |
d107198f | 711 | { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256, |
b7c167f9 | 712 | KEY_RSA, KE_NONE, |
4cdade5a | 713 | HASH_SHA256, PRF_HMAC_SHA2_256, |
d107198f | 714 | AUTH_HMAC_SHA2_256_256, ENCR_CAMELLIA_CBC, 32, |
281766c5 | 715 | TLS_1_2, TLS_1_2, |
6e413d9c MW |
716 | }, |
717 | { TLS_RSA_WITH_CAMELLIA_256_CBC_SHA, | |
b7c167f9 | 718 | KEY_RSA, KE_NONE, |
ed57dfca | 719 | HASH_SHA256, PRF_HMAC_SHA2_256, |
7a2b0266 | 720 | AUTH_HMAC_SHA1_160, ENCR_CAMELLIA_CBC, 32, |
281766c5 | 721 | SSL_3_0, TLS_1_2, |
6e413d9c | 722 | }, |
d107198f | 723 | { TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256, |
b7c167f9 | 724 | KEY_RSA, KE_NONE, |
4cdade5a | 725 | HASH_SHA256, PRF_HMAC_SHA2_256, |
d107198f | 726 | AUTH_HMAC_SHA2_256_256, ENCR_CAMELLIA_CBC, 16, |
281766c5 | 727 | TLS_1_2, TLS_1_2, |
84543e6e | 728 | }, |
d107198f | 729 | { TLS_RSA_WITH_CAMELLIA_128_CBC_SHA, |
b7c167f9 | 730 | KEY_RSA, KE_NONE, |
ed57dfca | 731 | HASH_SHA256, PRF_HMAC_SHA2_256, |
d107198f | 732 | AUTH_HMAC_SHA1_160, ENCR_CAMELLIA_CBC, 16, |
281766c5 | 733 | SSL_3_0, TLS_1_2, |
2bf0e74c | 734 | }, |
2066918d MW |
735 | { TLS_ECDHE_ECDSA_WITH_NULL_SHA, |
736 | KEY_ECDSA, ECP_256_BIT, | |
ed57dfca | 737 | HASH_SHA256, PRF_HMAC_SHA2_256, |
7a2b0266 | 738 | AUTH_HMAC_SHA1_160, ENCR_NULL, 0, |
281766c5 | 739 | TLS_1_0, TLS_1_2, |
2066918d MW |
740 | }, |
741 | { TLS_ECDHE_RSA_WITH_NULL_SHA, | |
742 | KEY_ECDSA, ECP_256_BIT, | |
ed57dfca | 743 | HASH_SHA256, PRF_HMAC_SHA2_256, |
7a2b0266 | 744 | AUTH_HMAC_SHA1_160, ENCR_NULL, 0, |
281766c5 | 745 | TLS_1_0, TLS_1_2, |
2066918d | 746 | }, |
2bf0e74c | 747 | { TLS_RSA_WITH_NULL_SHA256, |
b7c167f9 | 748 | KEY_RSA, KE_NONE, |
4cdade5a | 749 | HASH_SHA256, PRF_HMAC_SHA2_256, |
7a2b0266 | 750 | AUTH_HMAC_SHA2_256_256, ENCR_NULL, 0, |
281766c5 | 751 | TLS_1_2, TLS_1_2, |
2bf0e74c | 752 | }, |
d107198f | 753 | { TLS_RSA_WITH_NULL_SHA, |
b7c167f9 | 754 | KEY_RSA, KE_NONE, |
ed57dfca | 755 | HASH_SHA256, PRF_HMAC_SHA2_256, |
d107198f PK |
756 | AUTH_HMAC_SHA1_160, ENCR_NULL, 0, |
757 | SSL_3_0, TLS_1_2, | |
2bf0e74c | 758 | }, |
84543e6e MW |
759 | }; |
760 | ||
761 | /** | |
f3bb1bd0 | 762 | * Look up algorithms by a suite |
84543e6e MW |
763 | */ |
764 | static suite_algs_t *find_suite(tls_cipher_suite_t suite) | |
765 | { | |
766 | int i; | |
767 | ||
768 | for (i = 0; i < countof(suite_algs); i++) | |
769 | { | |
770 | if (suite_algs[i].suite == suite) | |
771 | { | |
772 | return &suite_algs[i]; | |
773 | } | |
774 | } | |
775 | return NULL; | |
776 | } | |
777 | ||
18010de2 | 778 | /** |
a2bfc45b | 779 | * Filter a suite list using a transform enumerator |
18010de2 | 780 | */ |
ac5717c9 | 781 | static void filter_suite(suite_algs_t suites[], int *count, int offset, |
a2bfc45b | 782 | enumerator_t*(*create_enumerator)(crypto_factory_t*)) |
536dbc00 | 783 | { |
5932f41f | 784 | const char *plugin_name; |
a2bfc45b | 785 | suite_algs_t current; |
f10e7234 | 786 | int *current_alg, i, remaining = 0; |
a2bfc45b | 787 | enumerator_t *enumerator; |
536dbc00 | 788 | |
a2bfc45b | 789 | memset(¤t, 0, sizeof(current)); |
f10e7234 AS |
790 | current_alg = (int*)((char*)¤t + offset); |
791 | ||
a2bfc45b | 792 | for (i = 0; i < *count; i++) |
536dbc00 | 793 | { |
b886dad4 MW |
794 | if (create_enumerator == lib->crypto->create_crypter_enumerator && |
795 | encryption_algorithm_is_aead(suites[i].encr)) | |
796 | { /* filtering crypters, but current suite uses an AEAD, apply */ | |
797 | suites[remaining] = suites[i]; | |
798 | remaining++; | |
799 | continue; | |
800 | } | |
801 | if (create_enumerator == lib->crypto->create_aead_enumerator && | |
802 | !encryption_algorithm_is_aead(suites[i].encr)) | |
803 | { /* filtering AEADs, but current suite doesn't use one, apply */ | |
804 | suites[remaining] = suites[i]; | |
805 | remaining++; | |
806 | continue; | |
807 | } | |
a2bfc45b | 808 | enumerator = create_enumerator(lib->crypto); |
f10e7234 | 809 | while (enumerator->enumerate(enumerator, current_alg, &plugin_name)) |
536dbc00 | 810 | { |
b886dad4 | 811 | if (current.encr && current.encr != suites[i].encr) |
536dbc00 | 812 | { |
b886dad4 MW |
813 | if (suites[i].encr != ENCR_NULL) |
814 | { /* skip, ENCR does not match nor is NULL */ | |
815 | continue; | |
816 | } | |
536dbc00 | 817 | } |
b886dad4 MW |
818 | if (current.mac && current.mac != suites[i].mac) |
819 | { | |
820 | if (suites[i].mac != AUTH_UNDEFINED) | |
821 | { /* skip, MAC does not match nor is it undefined */ | |
822 | continue; | |
823 | } | |
824 | } | |
825 | if (current.prf && current.prf != suites[i].prf) | |
436571b2 TB |
826 | { |
827 | if (suites[i].prf != PRF_UNDEFINED) | |
828 | { | |
829 | /* skip, PRF does not match nor is it undefined */ | |
830 | continue; | |
831 | } | |
b886dad4 MW |
832 | } |
833 | if (current.hash && current.hash != suites[i].hash) | |
834 | { /* skip, hash does not match */ | |
835 | continue; | |
836 | } | |
837 | if (current.dh && current.dh != suites[i].dh) | |
838 | { | |
b7c167f9 | 839 | if (suites[i].dh != KE_NONE && |
3af7c6db TB |
840 | !(key_exchange_is_ecdh(current.dh) && |
841 | key_exchange_is_ecdh(suites[i].dh))) | |
311405c3 | 842 | { /* skip DH group, does not match nor NONE nor both ECDH */ |
b886dad4 MW |
843 | continue; |
844 | } | |
845 | } | |
846 | /* suite supported, apply */ | |
847 | suites[remaining] = suites[i]; | |
848 | remaining++; | |
849 | break; | |
536dbc00 | 850 | } |
a2bfc45b | 851 | enumerator->destroy(enumerator); |
536dbc00 | 852 | } |
a2bfc45b MW |
853 | *count = remaining; |
854 | } | |
855 | ||
96b2fbcc MW |
856 | /** |
857 | * Purge NULL encryption cipher suites from list | |
858 | */ | |
ac5717c9 | 859 | static void filter_null_suites(suite_algs_t suites[], int *count) |
96b2fbcc MW |
860 | { |
861 | int i, remaining = 0; | |
862 | ||
863 | for (i = 0; i < *count; i++) | |
864 | { | |
865 | if (suites[i].encr != ENCR_NULL) | |
866 | { | |
867 | suites[remaining] = suites[i]; | |
868 | remaining++; | |
869 | } | |
870 | } | |
871 | *count = remaining; | |
872 | } | |
873 | ||
4254257f MW |
874 | /** |
875 | * Purge suites using a given key type | |
876 | */ | |
877 | static void filter_key_suites(private_tls_crypto_t *this, | |
878 | suite_algs_t suites[], int *count, key_type_t key) | |
879 | { | |
880 | int i, remaining = 0; | |
881 | ||
882 | DBG2(DBG_TLS, "disabling %N suites, no backend found", key_type_names, key); | |
883 | for (i = 0; i < *count; i++) | |
884 | { | |
885 | if (suites[i].key != key) | |
886 | { | |
887 | suites[remaining] = suites[i]; | |
888 | remaining++; | |
889 | } | |
890 | } | |
891 | *count = remaining; | |
892 | } | |
893 | ||
24a5b935 MW |
894 | /** |
895 | * Filter suites by key exchange user config | |
896 | */ | |
897 | static void filter_key_exchange_config_suites(private_tls_crypto_t *this, | |
898 | suite_algs_t suites[], int *count) | |
899 | { | |
900 | enumerator_t *enumerator; | |
901 | int i, remaining = 0; | |
902 | char *token, *config; | |
903 | ||
409adef4 TB |
904 | config = lib->settings->get_str(lib->settings, "%s.tls.key_exchange", NULL, |
905 | lib->ns); | |
24a5b935 MW |
906 | if (config) |
907 | { | |
908 | for (i = 0; i < *count; i++) | |
909 | { | |
910 | enumerator = enumerator_create_token(config, ",", " "); | |
911 | while (enumerator->enumerate(enumerator, &token)) | |
912 | { | |
913 | if (strcaseeq(token, "ecdhe-ecdsa") && | |
3af7c6db | 914 | key_exchange_is_ecdh(suites[i].dh) && |
24a5b935 MW |
915 | suites[i].key == KEY_ECDSA) |
916 | { | |
917 | suites[remaining++] = suites[i]; | |
918 | break; | |
919 | } | |
920 | if (strcaseeq(token, "ecdhe-rsa") && | |
3af7c6db | 921 | key_exchange_is_ecdh(suites[i].dh) && |
24a5b935 MW |
922 | suites[i].key == KEY_RSA) |
923 | { | |
924 | suites[remaining++] = suites[i]; | |
925 | break; | |
926 | } | |
927 | if (strcaseeq(token, "dhe-rsa") && | |
3af7c6db | 928 | !key_exchange_is_ecdh(suites[i].dh) && |
b7c167f9 | 929 | suites[i].dh != KE_NONE && |
24a5b935 MW |
930 | suites[i].key == KEY_RSA) |
931 | { | |
932 | suites[remaining++] = suites[i]; | |
933 | break; | |
934 | } | |
935 | if (strcaseeq(token, "rsa") && | |
b7c167f9 | 936 | suites[i].dh == KE_NONE && |
24a5b935 MW |
937 | suites[i].key == KEY_RSA) |
938 | { | |
939 | suites[remaining++] = suites[i]; | |
940 | break; | |
941 | } | |
942 | } | |
943 | enumerator->destroy(enumerator); | |
944 | } | |
945 | *count = remaining; | |
946 | } | |
947 | } | |
948 | ||
949 | /** | |
950 | * Filter suites by cipher user config | |
951 | */ | |
952 | static void filter_cipher_config_suites(private_tls_crypto_t *this, | |
953 | suite_algs_t suites[], int *count) | |
954 | { | |
955 | enumerator_t *enumerator; | |
956 | int i, remaining = 0; | |
957 | char *token, *config; | |
958 | ||
409adef4 TB |
959 | config = lib->settings->get_str(lib->settings, "%s.tls.cipher", NULL, |
960 | lib->ns); | |
24a5b935 MW |
961 | if (config) |
962 | { | |
963 | for (i = 0; i < *count; i++) | |
964 | { | |
965 | enumerator = enumerator_create_token(config, ",", " "); | |
966 | while (enumerator->enumerate(enumerator, &token)) | |
967 | { | |
74b9ba7c TB |
968 | const proposal_token_t *tok; |
969 | ||
970 | tok = lib->proposal->get_token(lib->proposal, token); | |
971 | if (tok != NULL && tok->type == ENCRYPTION_ALGORITHM && | |
972 | suites[i].encr == tok->algorithm && | |
973 | (!tok->keysize || suites[i].encr_size == tok->keysize / 8)) | |
24a5b935 MW |
974 | { |
975 | suites[remaining++] = suites[i]; | |
976 | break; | |
977 | } | |
978 | } | |
979 | enumerator->destroy(enumerator); | |
980 | } | |
981 | *count = remaining; | |
982 | } | |
983 | } | |
984 | ||
985 | /** | |
986 | * Filter suites by mac user config | |
987 | */ | |
988 | static void filter_mac_config_suites(private_tls_crypto_t *this, | |
989 | suite_algs_t suites[], int *count) | |
990 | { | |
991 | enumerator_t *enumerator; | |
992 | int i, remaining = 0; | |
993 | char *token, *config; | |
994 | ||
409adef4 TB |
995 | config = lib->settings->get_str(lib->settings, "%s.tls.mac", NULL, |
996 | lib->ns); | |
24a5b935 MW |
997 | if (config) |
998 | { | |
999 | for (i = 0; i < *count; i++) | |
1000 | { | |
1001 | enumerator = enumerator_create_token(config, ",", " "); | |
1002 | while (enumerator->enumerate(enumerator, &token)) | |
1003 | { | |
24a5b935 | 1004 | if (strcaseeq(token, "sha1") && |
1dabf5bf | 1005 | suites[i].mac == AUTH_HMAC_SHA1_160) |
24a5b935 MW |
1006 | { |
1007 | suites[remaining++] = suites[i]; | |
1008 | break; | |
1009 | } | |
1010 | if (strcaseeq(token, "sha256") && | |
1dabf5bf | 1011 | suites[i].mac == AUTH_HMAC_SHA2_256_256) |
24a5b935 MW |
1012 | { |
1013 | suites[remaining++] = suites[i]; | |
1014 | break; | |
1015 | } | |
1016 | if (strcaseeq(token, "sha384") && | |
1dabf5bf | 1017 | suites[i].mac == AUTH_HMAC_SHA2_384_384) |
24a5b935 MW |
1018 | { |
1019 | suites[remaining++] = suites[i]; | |
1020 | break; | |
1021 | } | |
1022 | } | |
1023 | enumerator->destroy(enumerator); | |
1024 | } | |
1025 | *count = remaining; | |
1026 | } | |
1027 | } | |
1028 | ||
adb913ad MW |
1029 | /** |
1030 | * Filter for specific suites specified in strongswan.conf | |
1031 | */ | |
1032 | static void filter_specific_config_suites(private_tls_crypto_t *this, | |
1033 | suite_algs_t suites[], int *count) | |
1034 | { | |
1035 | enumerator_t *enumerator; | |
1036 | int i, remaining = 0, suite; | |
1037 | char *token, *config; | |
1038 | ||
409adef4 TB |
1039 | config = lib->settings->get_str(lib->settings, "%s.tls.suites", NULL, |
1040 | lib->ns); | |
adb913ad MW |
1041 | if (config) |
1042 | { | |
1043 | for (i = 0; i < *count; i++) | |
1044 | { | |
1045 | enumerator = enumerator_create_token(config, ",", " "); | |
1046 | while (enumerator->enumerate(enumerator, &token)) | |
1047 | { | |
064fe9c9 MW |
1048 | if (enum_from_name(tls_cipher_suite_names, token, &suite) && |
1049 | suite == suites[i].suite) | |
adb913ad MW |
1050 | { |
1051 | suites[remaining++] = suites[i]; | |
1052 | break; | |
1053 | } | |
1054 | } | |
1055 | enumerator->destroy(enumerator); | |
1056 | } | |
1057 | *count = remaining; | |
1058 | } | |
1059 | } | |
1060 | ||
e53bee9d PK |
1061 | /** |
1062 | * Filter key exchange curves by curve user config | |
1063 | */ | |
1064 | static bool filter_curve_config(tls_named_group_t curve) | |
1065 | { | |
1066 | enumerator_t *enumerator; | |
1067 | char *token, *config; | |
1068 | ||
e5b65657 PK |
1069 | config = lib->settings->get_str(lib->settings, "%s.tls.ke_group", NULL, |
1070 | lib->ns); | |
e53bee9d PK |
1071 | if (config) |
1072 | { | |
1073 | enumerator = enumerator_create_token(config, ",", " "); | |
1074 | while (enumerator->enumerate(enumerator, &token)) | |
1075 | { | |
1076 | const proposal_token_t *tok; | |
1077 | ||
1078 | tok = lib->proposal->get_token(lib->proposal, token); | |
3af7c6db | 1079 | if (tok != NULL && tok->type == KEY_EXCHANGE_METHOD && |
e53bee9d PK |
1080 | curve == tls_ec_group_to_curve(tok->algorithm)) |
1081 | { | |
1082 | enumerator->destroy(enumerator); | |
1083 | return TRUE; | |
1084 | } | |
1085 | } | |
1086 | enumerator->destroy(enumerator); | |
1087 | } | |
1088 | return !config; | |
1089 | } | |
1090 | ||
ac5717c9 MW |
1091 | /** |
1092 | * Filter out unsupported suites on given suite array | |
1093 | */ | |
1094 | static void filter_unsupported_suites(suite_algs_t suites[], int *count) | |
1095 | { | |
1096 | /* filter suite list by each algorithm */ | |
436571b2 TB |
1097 | filter_suite(suites, count, offsetof(suite_algs_t, encr), |
1098 | lib->crypto->create_aead_enumerator); | |
1099 | filter_suite(suites, count, offsetof(suite_algs_t, prf), | |
1100 | lib->crypto->create_prf_enumerator); | |
ac5717c9 MW |
1101 | filter_suite(suites, count, offsetof(suite_algs_t, encr), |
1102 | lib->crypto->create_crypter_enumerator); | |
ac5717c9 MW |
1103 | filter_suite(suites, count, offsetof(suite_algs_t, mac), |
1104 | lib->crypto->create_signer_enumerator); | |
ac5717c9 MW |
1105 | filter_suite(suites, count, offsetof(suite_algs_t, hash), |
1106 | lib->crypto->create_hasher_enumerator); | |
1107 | filter_suite(suites, count, offsetof(suite_algs_t, dh), | |
3af7c6db | 1108 | lib->crypto->create_ke_enumerator); |
ac5717c9 MW |
1109 | } |
1110 | ||
a2bfc45b MW |
1111 | /** |
1112 | * Initialize the cipher suite list | |
1113 | */ | |
43c8f950 | 1114 | static void build_cipher_suite_list(private_tls_crypto_t *this) |
a2bfc45b | 1115 | { |
a6a0fa98 | 1116 | suite_algs_t suites[countof(suite_algs)] = {}; |
8a6edc08 | 1117 | tls_version_t min_version, max_version, new_min_version, new_max_version; |
11a46879 | 1118 | bool require_encryption = TRUE; |
281766c5 | 1119 | int count = 0, i; |
536dbc00 | 1120 | |
43c8f950 TB |
1121 | switch (this->tls->get_purpose(this->tls)) |
1122 | { | |
1123 | case TLS_PURPOSE_EAP_TLS: | |
43c8f950 TB |
1124 | require_encryption = FALSE; |
1125 | break; | |
43c8f950 | 1126 | case TLS_PURPOSE_GENERIC: |
11a46879 TB |
1127 | if (this->tls->get_flags(this->tls) & TLS_FLAG_ENCRYPTION_OPTIONAL) |
1128 | { | |
1129 | require_encryption = FALSE; | |
1130 | } | |
43c8f950 TB |
1131 | break; |
1132 | default: | |
11a46879 | 1133 | break; |
43c8f950 TB |
1134 | } |
1135 | ||
281766c5 TB |
1136 | min_version = this->tls->get_version_min(this->tls); |
1137 | max_version = this->tls->get_version_max(this->tls); | |
1138 | ||
1139 | /* copy all suites appropriate for the current min/max versions */ | |
1140 | for (i = 0; i < countof(suite_algs); i++) | |
536dbc00 | 1141 | { |
281766c5 TB |
1142 | if (suite_algs[i].min_version <= max_version && |
1143 | suite_algs[i].max_version >= min_version) | |
1144 | { | |
1145 | suites[count++] = suite_algs[i]; | |
1146 | } | |
18010de2 | 1147 | } |
ac5717c9 | 1148 | |
96b2fbcc MW |
1149 | if (require_encryption) |
1150 | { | |
ac5717c9 | 1151 | filter_null_suites(suites, &count); |
96b2fbcc | 1152 | } |
4254257f MW |
1153 | if (!this->rsa) |
1154 | { | |
1155 | filter_key_suites(this, suites, &count, KEY_RSA); | |
1156 | } | |
1157 | if (!this->ecdsa) | |
1158 | { | |
1159 | filter_key_suites(this, suites, &count, KEY_ECDSA); | |
1160 | } | |
1161 | ||
ac5717c9 | 1162 | filter_unsupported_suites(suites, &count); |
a2bfc45b | 1163 | |
24a5b935 MW |
1164 | /* filter suites with strongswan.conf options */ |
1165 | filter_key_exchange_config_suites(this, suites, &count); | |
1166 | filter_cipher_config_suites(this, suites, &count); | |
1167 | filter_mac_config_suites(this, suites, &count); | |
adb913ad | 1168 | filter_specific_config_suites(this, suites, &count); |
24a5b935 | 1169 | |
56a1167b AS |
1170 | free(this->suites); |
1171 | this->suite_count = count; | |
1172 | this->suites = malloc(sizeof(tls_cipher_suite_t) * count); | |
1173 | ||
3c19b346 | 1174 | DBG2(DBG_TLS, "%d supported TLS cipher suites:", count); |
8a6edc08 PK |
1175 | new_min_version = max_version; |
1176 | new_max_version = min_version; | |
a2bfc45b MW |
1177 | for (i = 0; i < count; i++) |
1178 | { | |
3c19b346 | 1179 | DBG2(DBG_TLS, " %N", tls_cipher_suite_names, suites[i].suite); |
56a1167b | 1180 | this->suites[i] = suites[i].suite; |
8a6edc08 PK |
1181 | |
1182 | /* set TLS min/max versions appropriate to the final cipher suites */ | |
1183 | new_max_version = max(new_max_version, suites[i].max_version); | |
1184 | new_min_version = min(new_min_version, suites[i].min_version); | |
1185 | } | |
1186 | new_max_version = min(new_max_version, max_version); | |
1187 | new_min_version = max(new_min_version, min_version); | |
1188 | ||
8cf3998f TB |
1189 | if ((min_version != new_min_version || max_version != new_max_version) && |
1190 | this->tls->set_version(this->tls, new_min_version, new_max_version)) | |
8a6edc08 | 1191 | { |
8a6edc08 | 1192 | DBG2(DBG_TLS, "TLS min/max %N/%N according to the cipher suites", |
8cf3998f TB |
1193 | tls_numeric_version_names, new_min_version, |
1194 | tls_numeric_version_names, new_max_version); | |
a2bfc45b | 1195 | } |
18010de2 MW |
1196 | } |
1197 | ||
1198 | METHOD(tls_crypto_t, get_cipher_suites, int, | |
1199 | private_tls_crypto_t *this, tls_cipher_suite_t **suites) | |
1200 | { | |
43c8f950 TB |
1201 | if (!this->suites) |
1202 | { | |
1203 | build_cipher_suite_list(this); | |
1204 | } | |
06424efa TB |
1205 | if (suites) |
1206 | { | |
1207 | *suites = this->suites; | |
1208 | } | |
18010de2 MW |
1209 | return this->suite_count; |
1210 | } | |
1211 | ||
d3204677 MW |
1212 | /** |
1213 | * Create NULL encryption transforms | |
1214 | */ | |
1215 | static bool create_null(private_tls_crypto_t *this, suite_algs_t *algs) | |
1216 | { | |
1217 | this->aead_in = tls_aead_create_null(algs->mac); | |
1218 | this->aead_out = tls_aead_create_null(algs->mac); | |
1219 | if (!this->aead_in || !this->aead_out) | |
1220 | { | |
1221 | DBG1(DBG_TLS, "selected TLS MAC %N not supported", | |
1222 | integrity_algorithm_names, algs->mac); | |
1223 | return FALSE; | |
1224 | } | |
1225 | return TRUE; | |
1226 | } | |
1227 | ||
1228 | /** | |
1229 | * Create traditional transforms | |
1230 | */ | |
1231 | static bool create_traditional(private_tls_crypto_t *this, suite_algs_t *algs) | |
1232 | { | |
7a2b0266 | 1233 | if (this->tls->get_version_max(this->tls) < TLS_1_1) |
d3204677 MW |
1234 | { |
1235 | this->aead_in = tls_aead_create_implicit(algs->mac, | |
1236 | algs->encr, algs->encr_size); | |
1237 | this->aead_out = tls_aead_create_implicit(algs->mac, | |
1238 | algs->encr, algs->encr_size); | |
1239 | } | |
1240 | else | |
1241 | { | |
1242 | this->aead_in = tls_aead_create_explicit(algs->mac, | |
1243 | algs->encr, algs->encr_size); | |
1244 | this->aead_out = tls_aead_create_explicit(algs->mac, | |
1245 | algs->encr, algs->encr_size); | |
1246 | } | |
1247 | if (!this->aead_in || !this->aead_out) | |
1248 | { | |
1249 | DBG1(DBG_TLS, "selected TLS transforms %N-%u-%N not supported", | |
1250 | encryption_algorithm_names, algs->encr, algs->encr_size * 8, | |
1251 | integrity_algorithm_names, algs->mac); | |
1252 | return FALSE; | |
1253 | } | |
1254 | return TRUE; | |
1255 | } | |
1256 | ||
f0f30117 MW |
1257 | /** |
1258 | * Create AEAD transforms | |
1259 | */ | |
1260 | static bool create_aead(private_tls_crypto_t *this, suite_algs_t *algs) | |
1261 | { | |
7a2b0266 | 1262 | if (this->tls->get_version_max(this->tls) < TLS_1_3) |
1263 | { | |
1264 | this->aead_in = tls_aead_create_aead(algs->encr, algs->encr_size); | |
1265 | this->aead_out = tls_aead_create_aead(algs->encr, algs->encr_size); | |
1266 | } | |
1267 | else | |
1268 | { | |
1269 | this->aead_in = tls_aead_create_seq(algs->encr, algs->encr_size); | |
1270 | this->aead_out = tls_aead_create_seq(algs->encr, algs->encr_size); | |
7a2b0266 | 1271 | } |
f0f30117 MW |
1272 | if (!this->aead_in || !this->aead_out) |
1273 | { | |
1274 | DBG1(DBG_TLS, "selected TLS transforms %N-%u not supported", | |
1275 | encryption_algorithm_names, algs->encr, algs->encr_size * 8); | |
1276 | return FALSE; | |
1277 | } | |
1278 | return TRUE; | |
1279 | } | |
1280 | ||
d3204677 MW |
1281 | /** |
1282 | * Clean up and unset AEAD transforms | |
1283 | */ | |
1284 | static void destroy_aeads(private_tls_crypto_t *this) | |
1285 | { | |
1286 | DESTROY_IF(this->aead_in); | |
1287 | DESTROY_IF(this->aead_out); | |
1288 | this->aead_in = this->aead_out = NULL; | |
1289 | } | |
1290 | ||
84543e6e MW |
1291 | /** |
1292 | * Create crypto primitives | |
1293 | */ | |
4cdade5a | 1294 | static bool create_ciphers(private_tls_crypto_t *this, suite_algs_t *algs) |
84543e6e | 1295 | { |
d3204677 | 1296 | destroy_aeads(this); |
64e63c68 | 1297 | DESTROY_IF(this->hkdf); |
84543e6e | 1298 | DESTROY_IF(this->prf); |
7a2b0266 | 1299 | if (this->tls->get_version_max(this->tls) < TLS_1_3) |
84543e6e | 1300 | { |
7a2b0266 | 1301 | if (this->tls->get_version_max(this->tls) < TLS_1_2) |
1302 | { | |
1303 | this->prf = tls_prf_create_10(); | |
1304 | } | |
1305 | else | |
1306 | { | |
1307 | this->prf = tls_prf_create_12(algs->prf); | |
1308 | } | |
1309 | if (!this->prf) | |
1310 | { | |
1311 | DBG1(DBG_TLS, "selected TLS PRF not supported"); | |
1312 | return FALSE; | |
1313 | } | |
84543e6e MW |
1314 | } |
1315 | else | |
1316 | { | |
7a2b0266 | 1317 | this->hkdf = tls_hkdf_create(algs->hash, chunk_empty); |
1318 | if (!this->hkdf) | |
1319 | { | |
1320 | DBG1(DBG_TLS, "TLS HKDF creation unsuccessful"); | |
1321 | return FALSE; | |
1322 | } | |
84543e6e | 1323 | } |
84543e6e MW |
1324 | if (algs->encr == ENCR_NULL) |
1325 | { | |
d3204677 MW |
1326 | if (create_null(this, algs)) |
1327 | { | |
1328 | return TRUE; | |
1329 | } | |
84543e6e | 1330 | } |
f0f30117 MW |
1331 | else if (encryption_algorithm_is_aead(algs->encr)) |
1332 | { | |
1333 | if (create_aead(this, algs)) | |
1334 | { | |
1335 | return TRUE; | |
1336 | } | |
1337 | } | |
84543e6e MW |
1338 | else |
1339 | { | |
d3204677 | 1340 | if (create_traditional(this, algs)) |
84543e6e | 1341 | { |
d3204677 | 1342 | return TRUE; |
84543e6e MW |
1343 | } |
1344 | } | |
d3204677 MW |
1345 | destroy_aeads(this); |
1346 | return FALSE; | |
84543e6e MW |
1347 | } |
1348 | ||
18010de2 | 1349 | METHOD(tls_crypto_t, select_cipher_suite, tls_cipher_suite_t, |
4cdade5a MW |
1350 | private_tls_crypto_t *this, tls_cipher_suite_t *suites, int count, |
1351 | key_type_t key) | |
18010de2 | 1352 | { |
4cdade5a | 1353 | suite_algs_t *algs; |
18010de2 MW |
1354 | int i, j; |
1355 | ||
1356 | for (i = 0; i < this->suite_count; i++) | |
1357 | { | |
1358 | for (j = 0; j < count; j++) | |
1359 | { | |
1360 | if (this->suites[i] == suites[j]) | |
1361 | { | |
4cdade5a MW |
1362 | algs = find_suite(this->suites[i]); |
1363 | if (algs) | |
84543e6e | 1364 | { |
34f66ce6 PK |
1365 | if (key == KEY_ANY || key == algs->key || |
1366 | (algs->key == KEY_ECDSA && key == KEY_ED25519) || | |
1367 | (algs->key == KEY_ECDSA && key == KEY_ED448)) | |
4cdade5a MW |
1368 | { |
1369 | if (create_ciphers(this, algs)) | |
1370 | { | |
1371 | this->suite = this->suites[i]; | |
1372 | return this->suite; | |
1373 | } | |
1374 | } | |
84543e6e | 1375 | } |
18010de2 MW |
1376 | } |
1377 | } | |
1378 | } | |
1379 | return 0; | |
1380 | } | |
1381 | ||
48d6b57c | 1382 | /** |
1b593e1d TB |
1383 | * Parameters for RSA/PSS signature schemes |
1384 | */ | |
1385 | #define PSS_PARAMS(bits) static rsa_pss_params_t pss_params_sha##bits = { \ | |
1386 | .hash = HASH_SHA##bits, \ | |
1387 | .mgf1_hash = HASH_SHA##bits, \ | |
1388 | .salt_len = HASH_SIZE_SHA##bits, \ | |
1389 | } | |
1390 | ||
1391 | PSS_PARAMS(256); | |
1392 | PSS_PARAMS(384); | |
1393 | PSS_PARAMS(512); | |
1394 | ||
e3757300 | 1395 | typedef struct { |
1b593e1d TB |
1396 | tls_signature_scheme_t sig; |
1397 | signature_params_t params; | |
1398 | /* min/max versions for use in CertificateVerify */ | |
1399 | tls_version_t min_version; | |
1400 | tls_version_t max_version; | |
e3757300 PK |
1401 | } scheme_algs_t; |
1402 | ||
1403 | /** | |
1404 | * Map TLS signature schemes, ordered by preference | |
1405 | */ | |
1406 | static scheme_algs_t schemes[] = { | |
1b593e1d TB |
1407 | { TLS_SIG_ECDSA_SHA256, { .scheme = SIGN_ECDSA_WITH_SHA256_DER }, |
1408 | TLS_1_0, TLS_1_3 }, | |
1409 | { TLS_SIG_ECDSA_SHA384, { .scheme = SIGN_ECDSA_WITH_SHA384_DER }, | |
1410 | TLS_1_0, TLS_1_3 }, | |
1411 | { TLS_SIG_ECDSA_SHA512, { .scheme = SIGN_ECDSA_WITH_SHA512_DER }, | |
1412 | TLS_1_0, TLS_1_3 }, | |
1413 | { TLS_SIG_ED25519, { .scheme = SIGN_ED25519 }, | |
34f66ce6 | 1414 | TLS_1_0, TLS_1_3 }, |
1b593e1d | 1415 | { TLS_SIG_ED448, { .scheme = SIGN_ED448 }, |
34f66ce6 | 1416 | TLS_1_0, TLS_1_3 }, |
1b593e1d TB |
1417 | { TLS_SIG_RSA_PSS_RSAE_SHA256, { .scheme = SIGN_RSA_EMSA_PSS, .params = &pss_params_sha256, }, |
1418 | TLS_1_2, TLS_1_3 }, | |
1419 | { TLS_SIG_RSA_PSS_RSAE_SHA384, { .scheme = SIGN_RSA_EMSA_PSS, .params = &pss_params_sha384, }, | |
1420 | TLS_1_2, TLS_1_3 }, | |
1421 | { TLS_SIG_RSA_PSS_RSAE_SHA512, { .scheme = SIGN_RSA_EMSA_PSS, .params = &pss_params_sha512, }, | |
1422 | TLS_1_2, TLS_1_3 }, | |
1423 | /* the parameters for the next three should actually be taken from the | |
1424 | * public key, we currently don't have an API for that, so assume defaults */ | |
1425 | { TLS_SIG_RSA_PSS_PSS_SHA256, { .scheme = SIGN_RSA_EMSA_PSS, .params = &pss_params_sha256, }, | |
1426 | TLS_1_2, TLS_1_3 }, | |
1427 | { TLS_SIG_RSA_PSS_PSS_SHA384, { .scheme = SIGN_RSA_EMSA_PSS, .params = &pss_params_sha384, }, | |
1428 | TLS_1_2, TLS_1_3 }, | |
1429 | { TLS_SIG_RSA_PSS_PSS_SHA512, { .scheme = SIGN_RSA_EMSA_PSS, .params = &pss_params_sha512, }, | |
1430 | TLS_1_2, TLS_1_3 }, | |
1431 | { TLS_SIG_RSA_PKCS1_SHA256, { .scheme = SIGN_RSA_EMSA_PKCS1_SHA2_256 }, | |
1432 | TLS_1_0, TLS_1_2 }, | |
1433 | { TLS_SIG_RSA_PKCS1_SHA384, { .scheme = SIGN_RSA_EMSA_PKCS1_SHA2_384 }, | |
1434 | TLS_1_0, TLS_1_2 }, | |
1435 | { TLS_SIG_RSA_PKCS1_SHA512, { .scheme = SIGN_RSA_EMSA_PKCS1_SHA2_512 }, | |
1436 | TLS_1_0, TLS_1_2 }, | |
48d6b57c MW |
1437 | }; |
1438 | ||
e3757300 PK |
1439 | /** |
1440 | * Filter signature scheme config | |
1441 | */ | |
1442 | static bool filter_signature_scheme_config(tls_signature_scheme_t signature) | |
1443 | { | |
1444 | enumerator_t *enumerator; | |
1445 | char *token, *config; | |
1446 | ||
1447 | config = lib->settings->get_str(lib->settings, "%s.tls.signature", NULL, | |
1448 | lib->ns); | |
1449 | if (config) | |
1450 | { | |
1451 | enumerator = enumerator_create_token(config, ",", " "); | |
1452 | while (enumerator->enumerate(enumerator, &token)) | |
1453 | { | |
1454 | tls_signature_scheme_t sig; | |
1455 | ||
1456 | if (enum_from_name(tls_signature_scheme_names, token, &sig) && | |
1457 | sig == signature) | |
1458 | { | |
1459 | enumerator->destroy(enumerator); | |
1460 | return TRUE; | |
1461 | } | |
1462 | } | |
1463 | enumerator->destroy(enumerator); | |
1464 | } | |
1465 | return !config; | |
1466 | } | |
1467 | ||
d29a82a9 | 1468 | METHOD(tls_crypto_t, get_signature_algorithms, void, |
1b593e1d | 1469 | private_tls_crypto_t *this, bio_writer_t *writer, bool cert) |
d29a82a9 | 1470 | { |
7e432eff | 1471 | bio_writer_t *supported; |
1b593e1d | 1472 | tls_version_t min_version, max_version; |
48d6b57c | 1473 | int i; |
d29a82a9 | 1474 | |
7e432eff | 1475 | supported = bio_writer_create(32); |
1b593e1d TB |
1476 | |
1477 | if (!cert) | |
1478 | { | |
1479 | min_version = this->tls->get_version_min(this->tls); | |
1480 | max_version = this->tls->get_version_max(this->tls); | |
1481 | } | |
48d6b57c MW |
1482 | |
1483 | for (i = 0; i < countof(schemes); i++) | |
d29a82a9 | 1484 | { |
1b593e1d TB |
1485 | if ((cert || (schemes[i].min_version <= max_version && |
1486 | schemes[i].max_version >= min_version)) && | |
1487 | lib->plugins->has_feature(lib->plugins, | |
e3757300 PK |
1488 | PLUGIN_PROVIDE(PUBKEY_VERIFY, schemes[i].params.scheme)) && |
1489 | filter_signature_scheme_config(schemes[i].sig)) | |
d29a82a9 | 1490 | { |
1b593e1d | 1491 | supported->write_uint16(supported, schemes[i].sig); |
7a2b0266 | 1492 | } |
d29a82a9 | 1493 | } |
d29a82a9 MW |
1494 | |
1495 | writer->write_data16(writer, supported->get_buf(supported)); | |
1496 | supported->destroy(supported); | |
1497 | } | |
1498 | ||
48d6b57c | 1499 | /** |
1b593e1d | 1500 | * Get the signature parameters from a TLS signature scheme |
48d6b57c | 1501 | */ |
06112f3f PK |
1502 | static signature_params_t *params_for_scheme(tls_signature_scheme_t sig, |
1503 | bool sign) | |
48d6b57c MW |
1504 | { |
1505 | int i; | |
1506 | ||
1b593e1d | 1507 | for (i = 0; i < countof(schemes); i++) |
48d6b57c | 1508 | { |
7fbe2e27 | 1509 | /* strongSwan supports only RSA_PSS_RSAE schemes for signing but can |
06112f3f PK |
1510 | * verify public keys in rsaEncryption as well as rsassaPss encoding. */ |
1511 | if (sign && (sig == TLS_SIG_RSA_PSS_PSS_SHA256 || | |
1512 | sig == TLS_SIG_RSA_PSS_PSS_SHA384 || | |
1513 | sig == TLS_SIG_RSA_PSS_PSS_SHA512)) | |
7fbe2e27 PK |
1514 | { |
1515 | continue; | |
1516 | } | |
1b593e1d | 1517 | if (schemes[i].sig == sig) |
48d6b57c | 1518 | { |
1b593e1d | 1519 | return &schemes[i].params; |
48d6b57c MW |
1520 | } |
1521 | } | |
1b593e1d | 1522 | return NULL; |
48d6b57c MW |
1523 | } |
1524 | ||
3f7bb88b MW |
1525 | /** |
1526 | * Mapping groups to TLS named curves | |
1527 | */ | |
1528 | static struct { | |
3af7c6db | 1529 | key_exchange_method_t group; |
7a2b0266 | 1530 | tls_named_group_t curve; |
3f7bb88b MW |
1531 | } curves[] = { |
1532 | { ECP_256_BIT, TLS_SECP256R1}, | |
1533 | { ECP_384_BIT, TLS_SECP384R1}, | |
1534 | { ECP_521_BIT, TLS_SECP521R1}, | |
1535 | { ECP_224_BIT, TLS_SECP224R1}, | |
1536 | { ECP_192_BIT, TLS_SECP192R1}, | |
3101120c TB |
1537 | { CURVE_25519, TLS_CURVE25519}, |
1538 | { CURVE_448, TLS_CURVE448}, | |
3f7bb88b MW |
1539 | }; |
1540 | ||
525cc46c TB |
1541 | CALLBACK(group_filter, bool, |
1542 | void *null, enumerator_t *orig, va_list args) | |
3f7bb88b | 1543 | { |
3af7c6db | 1544 | key_exchange_method_t group, *group_out; |
e53bee9d | 1545 | tls_named_group_t curve, *curve_out; |
525cc46c | 1546 | char *plugin; |
3f7bb88b | 1547 | |
e53bee9d | 1548 | VA_ARGS_VGET(args, group_out, curve_out); |
525cc46c TB |
1549 | |
1550 | while (orig->enumerate(orig, &group, &plugin)) | |
3f7bb88b | 1551 | { |
e53bee9d PK |
1552 | curve = tls_ec_group_to_curve(group); |
1553 | if (curve) | |
3f7bb88b | 1554 | { |
e53bee9d | 1555 | if (group_out) |
3f7bb88b | 1556 | { |
e53bee9d PK |
1557 | *group_out = group; |
1558 | } | |
1559 | if (curve_out) | |
1560 | { | |
1561 | *curve_out = curve; | |
1562 | } | |
1563 | return TRUE; | |
1564 | } | |
1565 | } | |
1566 | return FALSE; | |
1567 | } | |
1568 | ||
1569 | CALLBACK(config_filter, bool, | |
1570 | void *null, enumerator_t *orig, va_list args) | |
1571 | { | |
3af7c6db | 1572 | key_exchange_method_t group, *group_out; |
e53bee9d PK |
1573 | tls_named_group_t curve, *curve_out; |
1574 | ||
1575 | VA_ARGS_VGET(args, group_out, curve_out); | |
1576 | ||
1577 | while (orig->enumerate(orig, &group, &curve)) | |
1578 | { | |
1579 | if (filter_curve_config(curve)) | |
f77ecf07 | 1580 | |
e53bee9d PK |
1581 | { |
1582 | if (group_out) | |
1583 | { | |
1584 | *group_out = group; | |
3f7bb88b | 1585 | } |
e53bee9d PK |
1586 | if (curve_out) |
1587 | { | |
1588 | *curve_out = curve; | |
1589 | } | |
1590 | return TRUE; | |
3f7bb88b MW |
1591 | } |
1592 | } | |
1593 | return FALSE; | |
1594 | } | |
1595 | ||
1596 | METHOD(tls_crypto_t, create_ec_enumerator, enumerator_t*, | |
1597 | private_tls_crypto_t *this) | |
37a59a8f | 1598 | { |
3f7bb88b | 1599 | return enumerator_create_filter( |
e53bee9d | 1600 | enumerator_create_filter( |
3af7c6db | 1601 | lib->crypto->create_ke_enumerator(lib->crypto), |
e53bee9d PK |
1602 | group_filter, NULL, NULL), |
1603 | config_filter, NULL, NULL); | |
37a59a8f MW |
1604 | } |
1605 | ||
f77ecf07 TB |
1606 | /** |
1607 | * Check if the given ECDH group is supported or return the first one we | |
1608 | * actually do support. | |
1609 | */ | |
3af7c6db TB |
1610 | static key_exchange_method_t supported_ec_group(private_tls_crypto_t *this, |
1611 | key_exchange_method_t orig) | |
f77ecf07 | 1612 | { |
b7c167f9 | 1613 | key_exchange_method_t current, first = KE_NONE; |
f77ecf07 TB |
1614 | enumerator_t *enumerator; |
1615 | ||
1616 | enumerator = create_ec_enumerator(this); | |
1617 | while (enumerator->enumerate(enumerator, ¤t, NULL)) | |
1618 | { | |
1619 | if (current == orig) | |
1620 | { | |
1621 | enumerator->destroy(enumerator); | |
1622 | return orig; | |
1623 | } | |
b7c167f9 | 1624 | else if (first == KE_NONE) |
f77ecf07 TB |
1625 | { |
1626 | first = current; | |
1627 | } | |
1628 | } | |
1629 | enumerator->destroy(enumerator); | |
1630 | return first; | |
1631 | } | |
1632 | ||
3af7c6db | 1633 | METHOD(tls_crypto_t, get_dh_group, key_exchange_method_t, |
f77ecf07 TB |
1634 | private_tls_crypto_t *this) |
1635 | { | |
1636 | suite_algs_t *algs; | |
1637 | ||
1638 | algs = find_suite(this->suite); | |
1639 | if (algs) | |
1640 | { | |
3af7c6db | 1641 | if (key_exchange_is_ecdh(algs->dh)) |
f77ecf07 TB |
1642 | { |
1643 | return supported_ec_group(this, algs->dh); | |
1644 | } | |
1645 | return algs->dh; | |
1646 | } | |
b7c167f9 | 1647 | return KE_NONE; |
f77ecf07 TB |
1648 | } |
1649 | ||
dc9f34be MW |
1650 | METHOD(tls_crypto_t, set_protection, void, |
1651 | private_tls_crypto_t *this, tls_protection_t *protection) | |
1652 | { | |
1653 | this->protection = protection; | |
1654 | } | |
1655 | ||
84d67ead MW |
1656 | METHOD(tls_crypto_t, append_handshake, void, |
1657 | private_tls_crypto_t *this, tls_handshake_type_t type, chunk_t data) | |
1658 | { | |
b12c53ce | 1659 | uint32_t header; |
84d67ead MW |
1660 | |
1661 | /* reconstruct handshake header */ | |
1662 | header = htonl(data.len | (type << 24)); | |
1663 | this->handshake = chunk_cat("mcc", this->handshake, | |
1664 | chunk_from_thing(header), data); | |
1665 | } | |
1666 | ||
1667 | /** | |
d29a82a9 | 1668 | * Create a hash using the suites HASH algorithm |
84d67ead | 1669 | */ |
d29a82a9 | 1670 | static bool hash_data(private_tls_crypto_t *this, chunk_t data, chunk_t *hash) |
84d67ead | 1671 | { |
7a2b0266 | 1672 | if (this->tls->get_version_max(this->tls) >= TLS_1_2) |
84d67ead MW |
1673 | { |
1674 | hasher_t *hasher; | |
1675 | suite_algs_t *alg; | |
1676 | ||
1677 | alg = find_suite(this->suite); | |
1678 | if (!alg) | |
1679 | { | |
1680 | return FALSE; | |
1681 | } | |
1682 | hasher = lib->crypto->create_hasher(lib->crypto, alg->hash); | |
87dd205b | 1683 | if (!hasher || !hasher->allocate_hash(hasher, data, hash)) |
84d67ead | 1684 | { |
3c19b346 | 1685 | DBG1(DBG_TLS, "%N not supported", hash_algorithm_names, alg->hash); |
87dd205b | 1686 | DESTROY_IF(hasher); |
84d67ead MW |
1687 | return FALSE; |
1688 | } | |
84d67ead MW |
1689 | hasher->destroy(hasher); |
1690 | } | |
1691 | else | |
1692 | { | |
1693 | hasher_t *md5, *sha1; | |
1694 | char buf[HASH_SIZE_MD5 + HASH_SIZE_SHA1]; | |
1695 | ||
1696 | md5 = lib->crypto->create_hasher(lib->crypto, HASH_MD5); | |
8bd6a30a | 1697 | if (!md5 || !md5->get_hash(md5, data, buf)) |
84d67ead | 1698 | { |
3c19b346 | 1699 | DBG1(DBG_TLS, "%N not supported", hash_algorithm_names, HASH_MD5); |
8bd6a30a | 1700 | DESTROY_IF(md5); |
84d67ead MW |
1701 | return FALSE; |
1702 | } | |
84d67ead MW |
1703 | md5->destroy(md5); |
1704 | sha1 = lib->crypto->create_hasher(lib->crypto, HASH_SHA1); | |
8bd6a30a | 1705 | if (!sha1 || !sha1->get_hash(sha1, data, buf + HASH_SIZE_MD5)) |
84d67ead | 1706 | { |
3c19b346 | 1707 | DBG1(DBG_TLS, "%N not supported", hash_algorithm_names, HASH_SHA1); |
8bd6a30a | 1708 | DESTROY_IF(sha1); |
84d67ead MW |
1709 | return FALSE; |
1710 | } | |
84d67ead MW |
1711 | sha1->destroy(sha1); |
1712 | ||
1713 | *hash = chunk_clone(chunk_from_thing(buf)); | |
1714 | } | |
1715 | return TRUE; | |
1716 | } | |
1717 | ||
2271d67f TB |
1718 | METHOD(tls_crypto_t, hash_handshake, bool, |
1719 | private_tls_crypto_t *this, chunk_t *out) | |
1720 | { | |
1721 | chunk_t hash; | |
1722 | ||
1723 | if (!hash_data(this, this->handshake, &hash)) | |
1724 | { | |
1725 | return FALSE; | |
1726 | } | |
1727 | ||
1728 | chunk_free(&this->handshake); | |
1729 | append_handshake(this, TLS_MESSAGE_HASH, hash); | |
1730 | ||
1731 | if (out) | |
1732 | { | |
1733 | *out = hash; | |
1734 | } | |
1735 | else | |
1736 | { | |
1737 | free(hash.ptr); | |
1738 | } | |
1739 | return TRUE; | |
1740 | } | |
1741 | ||
de983a3c TB |
1742 | /** |
1743 | * TLS 1.3 static part of the data the server signs (64 spaces followed by the | |
1744 | * context string "TLS 1.3, server CertificateVerify" and a 0 byte). | |
1745 | */ | |
1746 | static chunk_t tls13_sig_data_server = chunk_from_chars( | |
1747 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | |
1748 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | |
1749 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | |
1750 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | |
1751 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | |
1752 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | |
1753 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | |
1754 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | |
1755 | 0x54, 0x4c, 0x53, 0x20, 0x31, 0x2e, 0x33, 0x2c, | |
1756 | 0x20, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, | |
1757 | 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, | |
1758 | 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x69, 0x66, | |
1759 | 0x79, 0x00, | |
1760 | ); | |
1761 | ||
d2fc9b09 PK |
1762 | /** |
1763 | * TLS 1.3 static part of the data the peer signs (64 spaces followed by the | |
1764 | * context string "TLS 1.3, client CertificateVerify" and a 0 byte). | |
1765 | */ | |
1766 | static chunk_t tls13_sig_data_client = chunk_from_chars( | |
1767 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | |
1768 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | |
1769 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | |
1770 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | |
1771 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | |
1772 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | |
1773 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | |
1774 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, | |
1775 | 0x54, 0x4c, 0x53, 0x20, 0x31, 0x2e, 0x33, 0x2c, | |
1776 | 0x20, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x20, | |
1777 | 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, | |
1778 | 0x61, 0x74, 0x65, 0x56, 0x65, 0x72, 0x69, 0x66, | |
1779 | 0x79, 0x00, | |
1780 | ); | |
1781 | ||
d29a82a9 | 1782 | METHOD(tls_crypto_t, sign, bool, |
7e432eff | 1783 | private_tls_crypto_t *this, private_key_t *key, bio_writer_t *writer, |
d29a82a9 | 1784 | chunk_t data, chunk_t hashsig) |
dbb7c030 | 1785 | { |
7a2b0266 | 1786 | if (this->tls->get_version_max(this->tls) >= TLS_1_2) |
84d67ead | 1787 | { |
1b593e1d TB |
1788 | /* fallback to SHA1/RSA and SHA1/ECDSA */ |
1789 | const chunk_t hashsig_def = chunk_from_chars(0x02, 0x01, 0x02, 0x03); | |
1790 | signature_params_t *params; | |
1791 | key_type_t type; | |
a4177033 | 1792 | uint16_t scheme = 0, hashsig_scheme; |
7e432eff | 1793 | bio_reader_t *reader; |
dbb7c030 MW |
1794 | chunk_t sig; |
1795 | bool done = FALSE; | |
1796 | ||
a4177033 | 1797 | |
7fbe2e27 PK |
1798 | if (this->tls->get_version_max(this->tls) >= TLS_1_3) |
1799 | { | |
1800 | chunk_t transcript_hash; | |
1801 | ||
1802 | if (!hash_data(this, data, &transcript_hash)) | |
1803 | { | |
1804 | DBG1(DBG_TLS, "unable to create transcript hash"); | |
1805 | return FALSE; | |
1806 | } | |
9ef46cfa PK |
1807 | if (this->tls->is_server(this->tls)) |
1808 | { | |
1809 | data = chunk_cata("cm", tls13_sig_data_server, transcript_hash); | |
1810 | } | |
1811 | else | |
1812 | { | |
1813 | data = chunk_cata("cm", tls13_sig_data_client, transcript_hash); | |
1814 | } | |
7fbe2e27 PK |
1815 | } |
1816 | ||
d29a82a9 MW |
1817 | if (!hashsig.len) |
1818 | { /* fallback if none given */ | |
d5cf2d1f | 1819 | hashsig = hashsig_def; |
d29a82a9 | 1820 | } |
a4177033 AS |
1821 | |
1822 | /* Determine TLS signature scheme if unique */ | |
1b593e1d | 1823 | type = key->get_type(key); |
a4177033 AS |
1824 | switch (type) |
1825 | { | |
1826 | case KEY_ED448: | |
1827 | scheme = TLS_SIG_ED448; | |
1828 | break; | |
1829 | case KEY_ED25519: | |
1830 | scheme = TLS_SIG_ED25519; | |
1831 | break; | |
1832 | case KEY_ECDSA: | |
1833 | switch (key->get_keysize(key)) | |
1834 | { | |
1835 | case 256: | |
1836 | scheme = TLS_SIG_ECDSA_SHA256; | |
1837 | break; | |
1838 | case 384: | |
1839 | scheme = TLS_SIG_ECDSA_SHA384; | |
1840 | break; | |
1841 | case 521: | |
1842 | scheme = TLS_SIG_ECDSA_SHA512; | |
1843 | break; | |
1844 | default: | |
1845 | DBG1(DBG_TLS, "%d bit ECDSA private key size not supported", | |
1846 | key->get_keysize(key)); | |
1847 | return FALSE; | |
1848 | } | |
1849 | break; | |
1850 | case KEY_RSA: | |
1851 | /* Several TLS signature schemes possible, select later on */ | |
1852 | break; | |
1853 | default: | |
1854 | DBG1(DBG_TLS, "%N private key type not supported", | |
1855 | key_type_names, type); | |
1856 | return FALSE; | |
1857 | } | |
1858 | ||
7e432eff | 1859 | reader = bio_reader_create(hashsig); |
dbb7c030 | 1860 | while (reader->remaining(reader) >= 2) |
400df4ca | 1861 | { |
a4177033 | 1862 | if (reader->read_uint16(reader, &hashsig_scheme)) |
dbb7c030 | 1863 | { |
a4177033 AS |
1864 | params = params_for_scheme(hashsig_scheme, TRUE); |
1865 | ||
1866 | /** | |
1867 | * All key types except RSA have a single fixed signature scheme | |
1868 | * RSA signature schemes are tried until sign() is successful | |
1869 | */ | |
1870 | if (params && (scheme == hashsig_scheme || | |
1871 | (!scheme && | |
2f3b327f TB |
1872 | type == key_type_from_signature_scheme(params->scheme) && |
1873 | filter_signature_scheme_config(hashsig_scheme)))) | |
dbb7c030 | 1874 | { |
a4177033 AS |
1875 | if (key->sign(key, params->scheme, params->params, data, &sig)) |
1876 | { | |
1877 | done = TRUE; | |
1878 | scheme = hashsig_scheme; | |
1879 | break; | |
1880 | } | |
dbb7c030 MW |
1881 | } |
1882 | } | |
1883 | } | |
1884 | reader->destroy(reader); | |
1885 | if (!done) | |
1886 | { | |
1887 | DBG1(DBG_TLS, "none of the proposed hash/sig algorithms supported"); | |
400df4ca MW |
1888 | return FALSE; |
1889 | } | |
a4177033 | 1890 | DBG1(DBG_TLS, "created signature with %N", tls_signature_scheme_names, |
1b593e1d TB |
1891 | scheme); |
1892 | writer->write_uint16(writer, scheme); | |
400df4ca MW |
1893 | writer->write_data16(writer, sig); |
1894 | free(sig.ptr); | |
1895 | } | |
1896 | else | |
1897 | { | |
dbb7c030 | 1898 | chunk_t sig, hash; |
d29a82a9 | 1899 | bool done; |
dbb7c030 MW |
1900 | |
1901 | switch (key->get_type(key)) | |
400df4ca | 1902 | { |
dbb7c030 | 1903 | case KEY_RSA: |
d29a82a9 | 1904 | if (!hash_data(this, data, &hash)) |
dbb7c030 MW |
1905 | { |
1906 | return FALSE; | |
1907 | } | |
de280c2e TB |
1908 | done = key->sign(key, SIGN_RSA_EMSA_PKCS1_NULL, NULL, hash, |
1909 | &sig); | |
d29a82a9 MW |
1910 | free(hash.ptr); |
1911 | if (!done) | |
dbb7c030 | 1912 | { |
dbb7c030 MW |
1913 | return FALSE; |
1914 | } | |
d29a82a9 | 1915 | DBG2(DBG_TLS, "created signature with MD5+SHA1/RSA"); |
dbb7c030 MW |
1916 | break; |
1917 | case KEY_ECDSA: | |
de280c2e | 1918 | if (!key->sign(key, SIGN_ECDSA_WITH_SHA1_DER, NULL, data, &sig)) |
dbb7c030 MW |
1919 | { |
1920 | return FALSE; | |
1921 | } | |
d29a82a9 | 1922 | DBG2(DBG_TLS, "created signature with SHA1/ECDSA"); |
dbb7c030 | 1923 | break; |
34f66ce6 PK |
1924 | case KEY_ED25519: |
1925 | if (!key->sign(key, SIGN_ED25519, NULL, data, &sig)) | |
1926 | { | |
1927 | return FALSE; | |
1928 | } | |
1929 | DBG2(DBG_TLS, "created signature with Ed25519"); | |
1930 | break; | |
1931 | case KEY_ED448: | |
1932 | if (!key->sign(key, SIGN_ED448, NULL, data, &sig)) | |
1933 | { | |
1934 | return FALSE; | |
1935 | } | |
1936 | DBG2(DBG_TLS, "created signature with Ed448"); | |
1937 | break; | |
dbb7c030 MW |
1938 | default: |
1939 | return FALSE; | |
400df4ca MW |
1940 | } |
1941 | writer->write_data16(writer, sig); | |
400df4ca MW |
1942 | free(sig.ptr); |
1943 | } | |
1944 | return TRUE; | |
1945 | } | |
1946 | ||
d29a82a9 | 1947 | METHOD(tls_crypto_t, verify, bool, |
7e432eff | 1948 | private_tls_crypto_t *this, public_key_t *key, bio_reader_t *reader, |
d29a82a9 | 1949 | chunk_t data) |
400df4ca | 1950 | { |
de983a3c | 1951 | if (this->tls->get_version_max(this->tls) >= TLS_1_2) |
7a2b0266 | 1952 | { |
1b593e1d TB |
1953 | signature_params_t *params; |
1954 | uint16_t scheme; | |
de983a3c | 1955 | chunk_t sig; |
7a2b0266 | 1956 | |
1b593e1d | 1957 | if (!reader->read_uint16(reader, &scheme) || |
7a2b0266 | 1958 | !reader->read_data16(reader, &sig)) |
1959 | { | |
1960 | DBG1(DBG_TLS, "received invalid signature"); | |
1961 | return FALSE; | |
1962 | } | |
06112f3f | 1963 | params = params_for_scheme(scheme, FALSE); |
1b593e1d | 1964 | if (!params) |
7a2b0266 | 1965 | { |
1b593e1d TB |
1966 | DBG1(DBG_TLS, "signature algorithms %N not supported", |
1967 | tls_signature_scheme_names, scheme); | |
7a2b0266 | 1968 | return FALSE; |
1969 | } | |
9ef46cfa | 1970 | if (this->tls->get_version_max(this->tls) >= TLS_1_3) |
7a2b0266 | 1971 | { |
de983a3c | 1972 | chunk_t transcript_hash; |
84d67ead | 1973 | |
de983a3c TB |
1974 | if (!hash_data(this, data, &transcript_hash)) |
1975 | { | |
1976 | DBG1(DBG_TLS, "Unable to create transcript hash"); | |
1977 | return FALSE; | |
1978 | } | |
1979 | ||
d2fc9b09 PK |
1980 | if (this->tls->is_server(this->tls)) |
1981 | { | |
1982 | data = chunk_cata("cm", tls13_sig_data_client, transcript_hash); | |
1983 | } | |
1984 | else | |
1985 | { | |
1986 | data = chunk_cata("cm", tls13_sig_data_server, transcript_hash); | |
1987 | } | |
84d67ead | 1988 | } |
1b593e1d | 1989 | if (!key->verify(key, params->scheme, params->params, data, sig)) |
dbb7c030 | 1990 | { |
1b593e1d TB |
1991 | DBG1(DBG_TLS, "signature verification with %N failed", |
1992 | tls_signature_scheme_names, scheme); | |
dbb7c030 MW |
1993 | return FALSE; |
1994 | } | |
1b593e1d TB |
1995 | DBG2(DBG_TLS, "verified signature with %N", |
1996 | tls_signature_scheme_names, scheme); | |
84d67ead MW |
1997 | } |
1998 | else | |
1999 | { | |
400df4ca | 2000 | chunk_t sig, hash; |
d29a82a9 | 2001 | bool done; |
84d67ead | 2002 | |
400df4ca MW |
2003 | if (!reader->read_data16(reader, &sig)) |
2004 | { | |
d29a82a9 | 2005 | DBG1(DBG_TLS, "received invalid signature"); |
400df4ca MW |
2006 | return FALSE; |
2007 | } | |
dbb7c030 | 2008 | switch (key->get_type(key)) |
84d67ead | 2009 | { |
dbb7c030 | 2010 | case KEY_RSA: |
d29a82a9 | 2011 | if (!hash_data(this, data, &hash)) |
dbb7c030 MW |
2012 | { |
2013 | return FALSE; | |
2014 | } | |
a413571f TB |
2015 | done = key->verify(key, SIGN_RSA_EMSA_PKCS1_NULL, NULL, hash, |
2016 | sig); | |
d29a82a9 MW |
2017 | free(hash.ptr); |
2018 | if (!done) | |
dbb7c030 | 2019 | { |
dbb7c030 MW |
2020 | return FALSE; |
2021 | } | |
d29a82a9 | 2022 | DBG2(DBG_TLS, "verified signature data with MD5+SHA1/RSA"); |
dbb7c030 MW |
2023 | break; |
2024 | case KEY_ECDSA: | |
a413571f TB |
2025 | if (!key->verify(key, SIGN_ECDSA_WITH_SHA1_DER, NULL, data, |
2026 | sig)) | |
dbb7c030 | 2027 | { |
dbb7c030 MW |
2028 | return FALSE; |
2029 | } | |
d29a82a9 | 2030 | DBG2(DBG_TLS, "verified signature with SHA1/ECDSA"); |
dbb7c030 | 2031 | break; |
34f66ce6 PK |
2032 | case KEY_ED25519: |
2033 | if (!key->verify(key, SIGN_ED25519, NULL, data, sig)) | |
2034 | { | |
2035 | return FALSE; | |
2036 | } | |
2037 | DBG2(DBG_TLS, "verified signature with Ed25519"); | |
2038 | break; | |
2039 | case KEY_ED448: | |
2040 | if (!key->verify(key, SIGN_ED448, NULL, data, sig)) | |
2041 | { | |
2042 | return FALSE; | |
2043 | } | |
2044 | DBG2(DBG_TLS, "verified signature with Ed448"); | |
2045 | break; | |
dbb7c030 MW |
2046 | default: |
2047 | return FALSE; | |
84d67ead | 2048 | } |
84d67ead MW |
2049 | } |
2050 | return TRUE; | |
2051 | } | |
2052 | ||
d29a82a9 | 2053 | METHOD(tls_crypto_t, sign_handshake, bool, |
7e432eff | 2054 | private_tls_crypto_t *this, private_key_t *key, bio_writer_t *writer, |
d29a82a9 MW |
2055 | chunk_t hashsig) |
2056 | { | |
2057 | return sign(this, key, writer, this->handshake, hashsig); | |
2058 | } | |
2059 | ||
2060 | METHOD(tls_crypto_t, verify_handshake, bool, | |
7e432eff | 2061 | private_tls_crypto_t *this, public_key_t *key, bio_reader_t *reader) |
d29a82a9 MW |
2062 | { |
2063 | return verify(this, key, reader, this->handshake); | |
2064 | } | |
2065 | ||
2e1c0a27 | 2066 | METHOD(tls_crypto_t, calculate_finished_legacy, bool, |
84d67ead MW |
2067 | private_tls_crypto_t *this, char *label, char out[12]) |
2068 | { | |
2069 | chunk_t seed; | |
2070 | ||
2071 | if (!this->prf) | |
2072 | { | |
2073 | return FALSE; | |
2074 | } | |
d29a82a9 | 2075 | if (!hash_data(this, this->handshake, &seed)) |
84d67ead MW |
2076 | { |
2077 | return FALSE; | |
2078 | } | |
97b30b93 MW |
2079 | if (!this->prf->get_bytes(this->prf, label, seed, 12, out)) |
2080 | { | |
2081 | free(seed.ptr); | |
2082 | return FALSE; | |
2083 | } | |
84d67ead MW |
2084 | free(seed.ptr); |
2085 | return TRUE; | |
2086 | } | |
2087 | ||
2e1c0a27 | 2088 | METHOD(tls_crypto_t, calculate_finished, bool, |
328d7af6 | 2089 | private_tls_crypto_t *this, bool server, chunk_t *out) |
7a2b0266 | 2090 | { |
2091 | chunk_t finished_key, finished_hash; | |
7a2b0266 | 2092 | |
f116a482 | 2093 | if (!this->hkdf) |
7a2b0266 | 2094 | { |
f116a482 | 2095 | return FALSE; |
7a2b0266 | 2096 | } |
f116a482 | 2097 | if (!hash_data(this, this->handshake, &finished_hash)) |
7a2b0266 | 2098 | { |
f116a482 TB |
2099 | DBG1(DBG_TLS, "creating hash of handshake failed"); |
2100 | return FALSE; | |
7a2b0266 | 2101 | } |
328d7af6 | 2102 | if (!this->hkdf->derive_finished(this->hkdf, server, &finished_key)) |
7a2b0266 | 2103 | { |
f116a482 TB |
2104 | DBG1(DBG_TLS, "generating finished key failed"); |
2105 | chunk_clear(&finished_hash); | |
2106 | return FALSE; | |
7a2b0266 | 2107 | } |
f116a482 | 2108 | if (!this->hkdf->allocate_bytes(this->hkdf, finished_key, finished_hash, out)) |
7a2b0266 | 2109 | { |
f116a482 | 2110 | DBG1(DBG_TLS, "generating finished HMAC failed"); |
7a2b0266 | 2111 | chunk_clear(&finished_key); |
2112 | chunk_clear(&finished_hash); | |
7a2b0266 | 2113 | return FALSE; |
2114 | } | |
7a2b0266 | 2115 | chunk_clear(&finished_key); |
2116 | chunk_clear(&finished_hash); | |
7a2b0266 | 2117 | return TRUE; |
2118 | } | |
2119 | ||
6a5c86b7 MW |
2120 | /** |
2121 | * Derive master secret from premaster, optionally save session | |
2122 | */ | |
97b30b93 | 2123 | static bool derive_master(private_tls_crypto_t *this, chunk_t premaster, |
6a5c86b7 MW |
2124 | chunk_t session, identification_t *id, |
2125 | chunk_t client_random, chunk_t server_random) | |
18010de2 | 2126 | { |
84543e6e | 2127 | char master[48]; |
6a5c86b7 | 2128 | chunk_t seed; |
84543e6e MW |
2129 | |
2130 | /* derive master secret */ | |
2131 | seed = chunk_cata("cc", client_random, server_random); | |
e7d98b8c MW |
2132 | |
2133 | if (!this->prf->set_key(this->prf, premaster) || | |
2134 | !this->prf->get_bytes(this->prf, "master secret", seed, | |
2135 | sizeof(master), master) || | |
2136 | !this->prf->set_key(this->prf, chunk_from_thing(master))) | |
97b30b93 MW |
2137 | { |
2138 | return FALSE; | |
2139 | } | |
97b30b93 | 2140 | |
6a5c86b7 MW |
2141 | if (this->cache && session.len) |
2142 | { | |
2143 | this->cache->create(this->cache, session, id, chunk_from_thing(master), | |
2144 | this->suite); | |
2145 | } | |
2146 | memwipe(master, sizeof(master)); | |
97b30b93 | 2147 | return TRUE; |
6a5c86b7 MW |
2148 | } |
2149 | ||
2150 | /** | |
2151 | * Expand key material from master secret | |
2152 | */ | |
9020f7d0 | 2153 | static bool expand_keys(private_tls_crypto_t *this, |
6a5c86b7 MW |
2154 | chunk_t client_random, chunk_t server_random) |
2155 | { | |
d3204677 MW |
2156 | chunk_t seed, block; |
2157 | chunk_t cw_mac, cw, cw_iv; | |
2158 | chunk_t sw_mac, sw, sw_iv; | |
2159 | int mklen, eklen, ivlen; | |
84543e6e | 2160 | |
d3204677 | 2161 | if (!this->aead_in || !this->aead_out) |
18010de2 | 2162 | { |
d3204677 | 2163 | return FALSE; |
84543e6e | 2164 | } |
d3204677 MW |
2165 | |
2166 | /* derive key block for key expansion */ | |
2167 | mklen = this->aead_in->get_mac_key_size(this->aead_in); | |
2168 | eklen = this->aead_in->get_encr_key_size(this->aead_in); | |
2169 | ivlen = this->aead_in->get_iv_size(this->aead_in); | |
84543e6e | 2170 | seed = chunk_cata("cc", server_random, client_random); |
d3204677 | 2171 | block = chunk_alloca((mklen + eklen + ivlen) * 2); |
97b30b93 MW |
2172 | if (!this->prf->get_bytes(this->prf, "key expansion", seed, |
2173 | block.len, block.ptr)) | |
2174 | { | |
2175 | return FALSE; | |
2176 | } | |
84543e6e | 2177 | |
d3204677 MW |
2178 | /* client/server write signer keys */ |
2179 | cw_mac = chunk_create(block.ptr, mklen); | |
2180 | block = chunk_skip(block, mklen); | |
2181 | sw_mac = chunk_create(block.ptr, mklen); | |
2182 | block = chunk_skip(block, mklen); | |
2183 | ||
2184 | /* client/server write encryption keys */ | |
2185 | cw = chunk_create(block.ptr, eklen); | |
2186 | block = chunk_skip(block, eklen); | |
2187 | sw = chunk_create(block.ptr, eklen); | |
2188 | block = chunk_skip(block, eklen); | |
2189 | ||
2190 | /* client/server write IV; TLS 1.0 implicit IVs or AEAD salt, if any */ | |
2191 | cw_iv = chunk_create(block.ptr, ivlen); | |
2192 | block = chunk_skip(block, ivlen); | |
2193 | sw_iv = chunk_create(block.ptr, ivlen); | |
2194 | block = chunk_skip(block, ivlen); | |
2195 | ||
84543e6e MW |
2196 | if (this->tls->is_server(this->tls)) |
2197 | { | |
d3204677 MW |
2198 | if (!this->aead_in->set_keys(this->aead_in, cw_mac, cw, cw_iv) || |
2199 | !this->aead_out->set_keys(this->aead_out, sw_mac, sw, sw_iv)) | |
2d56575d MW |
2200 | { |
2201 | return FALSE; | |
2202 | } | |
84543e6e MW |
2203 | } |
2204 | else | |
2205 | { | |
d3204677 MW |
2206 | if (!this->aead_out->set_keys(this->aead_out, cw_mac, cw, cw_iv) || |
2207 | !this->aead_in->set_keys(this->aead_in, sw_mac, sw, sw_iv)) | |
2d56575d MW |
2208 | { |
2209 | return FALSE; | |
2210 | } | |
84543e6e MW |
2211 | } |
2212 | ||
6a5c86b7 MW |
2213 | /* EAP-MSK */ |
2214 | if (this->msk_label) | |
2215 | { | |
06c15036 | 2216 | seed = chunk_cata("cc", client_random, server_random); |
6a5c86b7 | 2217 | this->msk = chunk_alloc(64); |
97b30b93 MW |
2218 | if (!this->prf->get_bytes(this->prf, this->msk_label, seed, |
2219 | this->msk.len, this->msk.ptr)) | |
2220 | { | |
2221 | return FALSE; | |
2222 | } | |
6a5c86b7 | 2223 | } |
9020f7d0 | 2224 | return TRUE; |
6a5c86b7 MW |
2225 | } |
2226 | ||
9020f7d0 | 2227 | METHOD(tls_crypto_t, derive_secrets, bool, |
6a5c86b7 MW |
2228 | private_tls_crypto_t *this, chunk_t premaster, chunk_t session, |
2229 | identification_t *id, chunk_t client_random, chunk_t server_random) | |
2230 | { | |
97b30b93 MW |
2231 | return derive_master(this, premaster, session, id, |
2232 | client_random, server_random) && | |
2233 | expand_keys(this, client_random, server_random); | |
6a5c86b7 MW |
2234 | } |
2235 | ||
2921f437 | 2236 | /** |
1466d4da | 2237 | * Derive and configure the client/server key/IV on an AEAD using a given label. |
2921f437 | 2238 | */ |
1466d4da TB |
2239 | static bool derive_labeled_key(private_tls_crypto_t *this, bool server, |
2240 | tls_hkdf_label_t label, tls_aead_t *aead) | |
7a2b0266 | 2241 | { |
1466d4da | 2242 | chunk_t key = chunk_empty, iv = chunk_empty; |
2921f437 | 2243 | bool success = FALSE; |
7a2b0266 | 2244 | |
1466d4da | 2245 | if (!this->hkdf->generate_secret(this->hkdf, label, this->handshake, |
2921f437 | 2246 | NULL) || |
1466d4da TB |
2247 | !this->hkdf->derive_key(this->hkdf, server, |
2248 | aead->get_encr_key_size(aead), &key) || | |
2249 | !this->hkdf->derive_iv(this->hkdf, server, | |
2250 | aead->get_iv_size(aead), &iv)) | |
2251 | { | |
2252 | DBG1(DBG_TLS, "deriving key material failed"); | |
2921f437 | 2253 | goto out; |
7a2b0266 | 2254 | } |
2255 | ||
1466d4da | 2256 | if (!aead->set_keys(aead, chunk_empty, key, iv)) |
7a2b0266 | 2257 | { |
2921f437 TB |
2258 | DBG1(DBG_TLS, "setting AEAD key material failed"); |
2259 | goto out; | |
7a2b0266 | 2260 | } |
2921f437 | 2261 | success = TRUE; |
7a2b0266 | 2262 | |
2921f437 | 2263 | out: |
1466d4da TB |
2264 | chunk_clear(&key); |
2265 | chunk_clear(&iv); | |
2921f437 | 2266 | return success; |
7a2b0266 | 2267 | } |
2268 | ||
1466d4da TB |
2269 | /** |
2270 | * Derive and configure the keys/IVs using the given labels. | |
2271 | */ | |
2272 | static bool derive_labeled_keys(private_tls_crypto_t *this, | |
2273 | tls_hkdf_label_t client_label, | |
2274 | tls_hkdf_label_t server_label) | |
2275 | { | |
6b23543a PK |
2276 | tls_aead_t *aead_c, *aead_s; |
2277 | suite_algs_t *algs; | |
1466d4da | 2278 | |
6b23543a PK |
2279 | algs = find_suite(this->suite); |
2280 | destroy_aeads(this); | |
2281 | if (!create_aead(this, algs)) | |
2282 | { | |
2283 | return FALSE; | |
2284 | } | |
2285 | aead_c = this->aead_out; | |
2286 | aead_s = this->aead_in; | |
1466d4da TB |
2287 | if (this->tls->is_server(this->tls)) |
2288 | { | |
2289 | aead_c = this->aead_in; | |
2290 | aead_s = this->aead_out; | |
2291 | } | |
2292 | return derive_labeled_key(this, FALSE, client_label, aead_c) && | |
2293 | derive_labeled_key(this, TRUE, server_label, aead_s); | |
2294 | } | |
2295 | ||
2921f437 TB |
2296 | METHOD(tls_crypto_t, derive_handshake_keys, bool, |
2297 | private_tls_crypto_t *this, chunk_t shared_secret) | |
7a2b0266 | 2298 | { |
2921f437 TB |
2299 | this->hkdf->set_shared_secret(this->hkdf, shared_secret); |
2300 | return derive_labeled_keys(this, TLS_HKDF_C_HS_TRAFFIC, | |
2301 | TLS_HKDF_S_HS_TRAFFIC); | |
2302 | } | |
7a2b0266 | 2303 | |
2921f437 TB |
2304 | METHOD(tls_crypto_t, derive_app_keys, bool, |
2305 | private_tls_crypto_t *this) | |
2306 | { | |
121ac4b9 TB |
2307 | if (!derive_labeled_keys(this, TLS_HKDF_C_AP_TRAFFIC, |
2308 | TLS_HKDF_S_AP_TRAFFIC)) | |
2309 | { | |
2310 | return FALSE; | |
2311 | } | |
2312 | ||
2313 | /* EAP-MSK */ | |
2314 | if (this->msk_label) | |
2315 | { | |
06abdf1d TB |
2316 | uint8_t type; |
2317 | ||
2318 | switch (this->tls->get_purpose(this->tls)) | |
2319 | { | |
2320 | case TLS_PURPOSE_EAP_TLS: | |
2321 | type = EAP_TLS; | |
2322 | break; | |
2323 | case TLS_PURPOSE_EAP_PEAP: | |
2324 | type = EAP_PEAP; | |
2325 | break; | |
2326 | case TLS_PURPOSE_EAP_TTLS: | |
2327 | type = EAP_TTLS; | |
2328 | break; | |
2329 | default: | |
2330 | return FALSE; | |
2331 | } | |
121ac4b9 | 2332 | /* because the length is encoded when expanding key material, we |
06abdf1d TB |
2333 | * request MSK and EMSK even if we don't use the latter */ |
2334 | if (!this->hkdf->export(this->hkdf, "EXPORTER_EAP_TLS_Key_Material", | |
2335 | chunk_from_thing(type), this->handshake, 128, | |
2336 | &this->msk)) | |
121ac4b9 TB |
2337 | { |
2338 | return FALSE; | |
2339 | } | |
2340 | this->msk.len = 64; | |
2341 | } | |
2342 | return TRUE; | |
7a2b0266 | 2343 | } |
2344 | ||
1466d4da TB |
2345 | METHOD(tls_crypto_t, update_app_keys, bool, |
2346 | private_tls_crypto_t *this, bool inbound) | |
2347 | { | |
6b23543a | 2348 | suite_algs_t *algs; |
1466d4da TB |
2349 | tls_hkdf_label_t label = TLS_HKDF_UPD_C_TRAFFIC; |
2350 | ||
6b23543a PK |
2351 | algs = find_suite(this->suite); |
2352 | destroy_aeads(this); | |
2353 | if (!create_aead(this, algs)) | |
2354 | { | |
2355 | return FALSE; | |
2356 | } | |
1466d4da TB |
2357 | if (this->tls->is_server(this->tls) != inbound) |
2358 | { | |
2359 | label = TLS_HKDF_UPD_S_TRAFFIC; | |
2360 | } | |
2361 | return derive_labeled_key(this, label == TLS_HKDF_UPD_S_TRAFFIC, label, | |
2362 | inbound ? this->aead_in : this->aead_out); | |
2363 | } | |
2364 | ||
6a5c86b7 MW |
2365 | METHOD(tls_crypto_t, resume_session, tls_cipher_suite_t, |
2366 | private_tls_crypto_t *this, chunk_t session, identification_t *id, | |
2367 | chunk_t client_random, chunk_t server_random) | |
2368 | { | |
2369 | chunk_t master; | |
2370 | ||
2371 | if (this->cache && session.len) | |
2372 | { | |
2373 | this->suite = this->cache->lookup(this->cache, session, id, &master); | |
2374 | if (this->suite) | |
2375 | { | |
ae10ee6d | 2376 | this->suite = select_cipher_suite(this, &this->suite, 1, KEY_ANY); |
6a5c86b7 MW |
2377 | if (this->suite) |
2378 | { | |
e7d98b8c MW |
2379 | if (!this->prf->set_key(this->prf, master) || |
2380 | !expand_keys(this, client_random, server_random)) | |
9020f7d0 MW |
2381 | { |
2382 | this->suite = 0; | |
2383 | } | |
6a5c86b7 MW |
2384 | } |
2385 | chunk_clear(&master); | |
2386 | } | |
ae10ee6d | 2387 | return this->suite; |
6a5c86b7 | 2388 | } |
ae10ee6d | 2389 | return 0; |
6a5c86b7 MW |
2390 | } |
2391 | ||
2392 | METHOD(tls_crypto_t, get_session, chunk_t, | |
2393 | private_tls_crypto_t *this, identification_t *server) | |
2394 | { | |
2395 | if (this->cache) | |
2396 | { | |
2397 | return this->cache->check(this->cache, server); | |
2398 | } | |
2399 | return chunk_empty; | |
84543e6e | 2400 | } |
18010de2 | 2401 | |
84543e6e MW |
2402 | METHOD(tls_crypto_t, change_cipher, void, |
2403 | private_tls_crypto_t *this, bool inbound) | |
2404 | { | |
dc9f34be | 2405 | if (this->protection) |
84543e6e | 2406 | { |
dc9f34be MW |
2407 | if (inbound) |
2408 | { | |
d3204677 | 2409 | this->protection->set_cipher(this->protection, TRUE, this->aead_in); |
6b23543a | 2410 | this->aead_in = NULL; |
dc9f34be MW |
2411 | } |
2412 | else | |
2413 | { | |
d3204677 | 2414 | this->protection->set_cipher(this->protection, FALSE, this->aead_out); |
6b23543a | 2415 | this->aead_out = NULL; |
dc9f34be | 2416 | } |
18010de2 | 2417 | } |
536dbc00 MW |
2418 | } |
2419 | ||
51313a39 MW |
2420 | METHOD(tls_crypto_t, get_eap_msk, chunk_t, |
2421 | private_tls_crypto_t *this) | |
2422 | { | |
2423 | return this->msk; | |
2424 | } | |
2425 | ||
536dbc00 MW |
2426 | METHOD(tls_crypto_t, destroy, void, |
2427 | private_tls_crypto_t *this) | |
2428 | { | |
d3204677 | 2429 | destroy_aeads(this); |
84d67ead | 2430 | free(this->handshake.ptr); |
51313a39 | 2431 | free(this->msk.ptr); |
18010de2 | 2432 | DESTROY_IF(this->prf); |
7a2b0266 | 2433 | DESTROY_IF(this->hkdf); |
84543e6e | 2434 | free(this->suites); |
536dbc00 MW |
2435 | free(this); |
2436 | } | |
2437 | ||
2438 | /** | |
2439 | * See header | |
2440 | */ | |
6a5c86b7 | 2441 | tls_crypto_t *tls_crypto_create(tls_t *tls, tls_cache_t *cache) |
536dbc00 MW |
2442 | { |
2443 | private_tls_crypto_t *this; | |
4254257f MW |
2444 | enumerator_t *enumerator; |
2445 | credential_type_t type; | |
2446 | int subtype; | |
536dbc00 MW |
2447 | |
2448 | INIT(this, | |
2449 | .public = { | |
2450 | .get_cipher_suites = _get_cipher_suites, | |
18010de2 | 2451 | .select_cipher_suite = _select_cipher_suite, |
35d9c15d | 2452 | .get_dh_group = _get_dh_group, |
d29a82a9 | 2453 | .get_signature_algorithms = _get_signature_algorithms, |
3f7bb88b | 2454 | .create_ec_enumerator = _create_ec_enumerator, |
dc9f34be | 2455 | .set_protection = _set_protection, |
84d67ead | 2456 | .append_handshake = _append_handshake, |
2271d67f | 2457 | .hash_handshake = _hash_handshake, |
d29a82a9 MW |
2458 | .sign = _sign, |
2459 | .verify = _verify, | |
84d67ead | 2460 | .sign_handshake = _sign_handshake, |
400df4ca | 2461 | .verify_handshake = _verify_handshake, |
2e1c0a27 | 2462 | .calculate_finished_legacy = _calculate_finished_legacy, |
84d67ead MW |
2463 | .calculate_finished = _calculate_finished, |
2464 | .derive_secrets = _derive_secrets, | |
2921f437 TB |
2465 | .derive_handshake_keys = _derive_handshake_keys, |
2466 | .derive_app_keys = _derive_app_keys, | |
1466d4da | 2467 | .update_app_keys = _update_app_keys, |
6a5c86b7 MW |
2468 | .resume_session = _resume_session, |
2469 | .get_session = _get_session, | |
84543e6e | 2470 | .change_cipher = _change_cipher, |
51313a39 | 2471 | .get_eap_msk = _get_eap_msk, |
536dbc00 MW |
2472 | .destroy = _destroy, |
2473 | }, | |
18010de2 | 2474 | .tls = tls, |
6a5c86b7 | 2475 | .cache = cache, |
536dbc00 MW |
2476 | ); |
2477 | ||
34f66ce6 PK |
2478 | /* FIXME: EDDSA keys are currently treated like ECDSA keys. A cleaner |
2479 | * separation would be welcome. */ | |
4254257f MW |
2480 | enumerator = lib->creds->create_builder_enumerator(lib->creds); |
2481 | while (enumerator->enumerate(enumerator, &type, &subtype)) | |
2482 | { | |
2483 | if (type == CRED_PUBLIC_KEY) | |
2484 | { | |
2485 | switch (subtype) | |
2486 | { | |
2487 | case KEY_RSA: | |
2488 | this->rsa = TRUE; | |
2489 | break; | |
2490 | case KEY_ECDSA: | |
34f66ce6 PK |
2491 | case KEY_ED25519: |
2492 | case KEY_ED448: | |
4254257f MW |
2493 | this->ecdsa = TRUE; |
2494 | break; | |
2495 | default: | |
2496 | break; | |
2497 | } | |
2498 | } | |
2499 | } | |
2500 | enumerator->destroy(enumerator); | |
2501 | ||
96b2fbcc MW |
2502 | switch (tls->get_purpose(tls)) |
2503 | { | |
2504 | case TLS_PURPOSE_EAP_TLS: | |
2505 | /* MSK PRF ASCII constant label according to EAP-TLS RFC 5216 */ | |
2506 | this->msk_label = "client EAP encryption"; | |
1407a002 | 2507 | break; |
ab2c989c MW |
2508 | case TLS_PURPOSE_EAP_PEAP: |
2509 | this->msk_label = "client EAP encryption"; | |
96b2fbcc MW |
2510 | break; |
2511 | case TLS_PURPOSE_EAP_TTLS: | |
2512 | /* MSK PRF ASCII constant label according to EAP-TTLS RFC 5281 */ | |
2513 | this->msk_label = "ttls keying material"; | |
ddf52220 | 2514 | break; |
99b0f633 AS |
2515 | default: |
2516 | break; | |
96b2fbcc | 2517 | } |
536dbc00 MW |
2518 | return &this->public; |
2519 | } | |
ac5717c9 MW |
2520 | |
2521 | /** | |
2522 | * See header. | |
2523 | */ | |
281766c5 TB |
2524 | int tls_crypto_get_supported_suites(bool null, tls_version_t version, |
2525 | tls_cipher_suite_t **out) | |
ac5717c9 | 2526 | { |
a6a0fa98 | 2527 | suite_algs_t suites[countof(suite_algs)] = {}; |
281766c5 | 2528 | int count = 0, i; |
ac5717c9 MW |
2529 | |
2530 | /* initialize copy of suite list */ | |
281766c5 | 2531 | for (i = 0; i < countof(suite_algs); i++) |
ac5717c9 | 2532 | { |
281766c5 TB |
2533 | if (suite_algs[i].min_version <= version && |
2534 | suite_algs[i].max_version >= version) | |
2535 | { | |
2536 | suites[count++] = suite_algs[i]; | |
2537 | } | |
ac5717c9 MW |
2538 | } |
2539 | ||
2540 | filter_unsupported_suites(suites, &count); | |
2541 | ||
2542 | if (!null) | |
2543 | { | |
2544 | filter_null_suites(suites, &count); | |
2545 | } | |
2546 | ||
2547 | if (out) | |
2548 | { | |
2549 | *out = calloc(count, sizeof(tls_cipher_suite_t)); | |
2550 | for (i = 0; i < count; i++) | |
2551 | { | |
2552 | (*out)[i] = suites[i].suite; | |
2553 | } | |
2554 | } | |
2555 | return count; | |
2556 | } | |
066ac880 | 2557 | |
e53bee9d PK |
2558 | /** |
2559 | * See header. | |
2560 | */ | |
3af7c6db | 2561 | int tls_crypto_get_supported_groups(key_exchange_method_t **out) |
e53bee9d PK |
2562 | { |
2563 | enumerator_t *enumerator; | |
3af7c6db TB |
2564 | key_exchange_method_t groups[countof(curves)]; |
2565 | key_exchange_method_t group; | |
e53bee9d PK |
2566 | tls_named_group_t curve; |
2567 | int count = 0, i; | |
2568 | ||
2569 | enumerator = enumerator_create_filter( | |
3af7c6db | 2570 | lib->crypto->create_ke_enumerator(lib->crypto), |
e53bee9d PK |
2571 | group_filter, NULL, NULL); |
2572 | ||
2573 | while (enumerator->enumerate(enumerator, &group, &curve)) | |
2574 | { | |
2575 | groups[count++] = group; | |
2576 | } | |
2577 | enumerator->destroy(enumerator); | |
2578 | ||
2579 | if (out) | |
2580 | { | |
3af7c6db | 2581 | *out = calloc(count, sizeof(key_exchange_method_t)); |
e53bee9d PK |
2582 | for (i = 0; i < count; i++) |
2583 | { | |
2584 | (*out)[i] = groups[i]; | |
2585 | } | |
2586 | } | |
2587 | return count; | |
2588 | } | |
2589 | ||
e3757300 PK |
2590 | /** |
2591 | * See header. | |
2592 | */ | |
2593 | int tls_crypto_get_supported_signatures(tls_version_t version, | |
2594 | tls_signature_scheme_t **out) | |
2595 | { | |
2596 | scheme_algs_t sigs[countof(schemes)]; | |
2597 | int count = 0, i; | |
2598 | ||
2599 | /* initialize copy of signature scheme list */ | |
2600 | for (i = 0; i < countof(schemes); i++) | |
2601 | { | |
2602 | /* only RSA_PSS_RSAE schemes supported for signing and verifying */ | |
2603 | if (schemes[i].sig == TLS_SIG_RSA_PSS_PSS_SHA256 || | |
2604 | schemes[i].sig == TLS_SIG_RSA_PSS_PSS_SHA384 || | |
2605 | schemes[i].sig == TLS_SIG_RSA_PSS_PSS_SHA512) | |
2606 | { | |
2607 | continue; | |
2608 | } | |
2609 | if (schemes[i].min_version <= version && | |
2610 | schemes[i].max_version >= version && | |
2611 | lib->plugins->has_feature(lib->plugins, | |
2612 | PLUGIN_PROVIDE(PUBKEY_VERIFY, schemes[i].params.scheme))) | |
2613 | { | |
2614 | sigs[count++] = schemes[i]; | |
2615 | } | |
2616 | } | |
2617 | ||
2618 | if (out) | |
2619 | { | |
2620 | *out = calloc(count, sizeof(tls_signature_scheme_t)); | |
2621 | for (i = 0; i < count; i++) | |
2622 | { | |
2623 | (*out)[i] = sigs[i].sig; | |
2624 | } | |
2625 | } | |
2626 | return count; | |
2627 | } | |
2628 | ||
066ac880 PK |
2629 | /** |
2630 | * See header. | |
2631 | */ | |
3af7c6db | 2632 | tls_named_group_t tls_ec_group_to_curve(key_exchange_method_t group) |
066ac880 PK |
2633 | { |
2634 | int i; | |
2635 | ||
2636 | for (i = 0; i < countof(curves); i++) | |
2637 | { | |
2638 | if (curves[i].group == group) | |
2639 | { | |
2640 | return curves[i].curve; | |
2641 | } | |
2642 | } | |
2643 | return 0; | |
2644 | } | |
9803fb82 PK |
2645 | |
2646 | /** | |
2647 | * See header. | |
2648 | */ | |
2649 | key_type_t tls_signature_scheme_to_key_type(tls_signature_scheme_t sig) | |
2650 | { | |
2651 | int i; | |
2652 | ||
2653 | for (i = 0; i < countof(schemes); i++) | |
2654 | { | |
2655 | if (schemes[i].sig == sig) | |
2656 | { | |
2657 | return key_type_from_signature_scheme(schemes[i].params.scheme); | |
2658 | } | |
2659 | } | |
2660 | return 0; | |
2661 | } | |
2662 | ||
2663 | /** | |
2664 | * Hashtable hash function | |
2665 | */ | |
2666 | static u_int hash_key_type(key_type_t *type) | |
2667 | { | |
2668 | return chunk_hash(chunk_from_thing(*type)); | |
2669 | } | |
2670 | ||
2671 | /** | |
2672 | * Hashtable equals function | |
2673 | */ | |
2674 | static bool equals_key_type(key_type_t *key1, key_type_t *key2) | |
2675 | { | |
2676 | return *key1 == *key2; | |
2677 | } | |
2678 | ||
2679 | CALLBACK(filter_key_types, bool, | |
2680 | void *data, enumerator_t *orig, va_list args) | |
2681 | { | |
2682 | key_type_t *key_type, *out; | |
2683 | ||
2684 | VA_ARGS_VGET(args, out); | |
2685 | ||
2686 | if (orig->enumerate(orig, NULL, &key_type)) | |
2687 | { | |
2688 | *out = *key_type; | |
2689 | return TRUE; | |
2690 | } | |
2691 | return FALSE; | |
2692 | } | |
2693 | ||
2694 | CALLBACK(destroy_key_types, void, | |
2695 | hashtable_t *ht) | |
2696 | { | |
2697 | ht->destroy_function(ht, (void*)free); | |
2698 | } | |
2699 | ||
d8e42a3d PK |
2700 | /** |
2701 | * Create an enumerator over supported key types within a specific TLS range | |
9803fb82 | 2702 | */ |
d8e42a3d | 2703 | static enumerator_t *get_supported_key_types(tls_version_t min_version, |
9803fb82 PK |
2704 | tls_version_t max_version) |
2705 | { | |
2706 | hashtable_t *ht; | |
2707 | key_type_t *type, lookup; | |
2708 | int i; | |
2709 | ||
2710 | ht = hashtable_create((hashtable_hash_t)hash_key_type, | |
2711 | (hashtable_equals_t)equals_key_type, 4); | |
2712 | for (i = 0; i < countof(schemes); i++) | |
2713 | { | |
2714 | if (schemes[i].min_version <= max_version && | |
2f3b327f TB |
2715 | schemes[i].max_version >= min_version && |
2716 | filter_signature_scheme_config(schemes[i].sig)) | |
9803fb82 PK |
2717 | { |
2718 | lookup = key_type_from_signature_scheme(schemes[i].params.scheme); | |
2719 | if (!ht->get(ht, &lookup)) | |
2720 | { | |
2721 | type = malloc_thing(key_type_t); | |
2722 | *type = lookup; | |
2723 | ht->put(ht, type, type); | |
2724 | } | |
2725 | } | |
2726 | } | |
2727 | return enumerator_create_filter(ht->create_enumerator(ht), | |
2728 | filter_key_types, ht, destroy_key_types); | |
2729 | } | |
d8e42a3d PK |
2730 | |
2731 | /** | |
2732 | * Create an array of an intersection of server and peer supported key types | |
2733 | */ | |
2734 | static array_t *create_common_key_types(enumerator_t *enumerator, chunk_t hashsig) | |
2735 | { | |
2736 | array_t *key_types; | |
2737 | key_type_t v, lookup; | |
2738 | uint16_t sig_scheme; | |
2739 | ||
2740 | key_types = array_create(sizeof(key_type_t), 8); | |
2741 | while (enumerator->enumerate(enumerator, &v)) | |
2742 | { | |
2743 | bio_reader_t *reader; | |
2744 | ||
2745 | reader = bio_reader_create(hashsig); | |
2746 | while (reader->remaining(reader) && | |
2747 | reader->read_uint16(reader, &sig_scheme)) | |
2748 | { | |
2749 | lookup = tls_signature_scheme_to_key_type(sig_scheme); | |
2750 | if (v == lookup) | |
2751 | { | |
2752 | array_insert(key_types, ARRAY_TAIL, &lookup); | |
2753 | break; | |
2754 | } | |
2755 | } | |
2756 | reader->destroy(reader); | |
2757 | } | |
2758 | return key_types; | |
2759 | } | |
2760 | ||
2761 | typedef struct { | |
2762 | enumerator_t public; | |
2763 | array_t *key_types; | |
2764 | identification_t *peer; | |
2765 | private_key_t *key; | |
2766 | auth_cfg_t *auth; | |
2767 | } private_key_enumerator_t; | |
2768 | ||
2769 | METHOD(enumerator_t, private_key_enumerate, bool, | |
2770 | private_key_enumerator_t *this, va_list args) | |
2771 | { | |
2772 | key_type_t type; | |
2773 | auth_cfg_t **auth_out; | |
2774 | private_key_t **key_out; | |
2775 | ||
2776 | VA_ARGS_VGET(args, key_out, auth_out); | |
2777 | ||
2778 | DESTROY_IF(this->key); | |
2779 | DESTROY_IF(this->auth); | |
2780 | this->auth = auth_cfg_create(); | |
2781 | ||
2782 | while (array_remove(this->key_types, ARRAY_HEAD, &type)) | |
2783 | { | |
2784 | this->key = lib->credmgr->get_private(lib->credmgr, type, this->peer, | |
2785 | this->auth); | |
2786 | if (this->key) | |
2787 | { | |
2788 | *key_out = this->key; | |
2789 | if (auth_out) | |
2790 | { | |
2791 | *auth_out = this->auth; | |
2792 | } | |
2793 | return TRUE; | |
2794 | } | |
2795 | } | |
2796 | return FALSE; | |
2797 | } | |
2798 | ||
2799 | METHOD(enumerator_t, private_key_destroy, void, | |
2800 | private_key_enumerator_t *this) | |
2801 | { | |
2802 | DESTROY_IF(this->key); | |
2803 | DESTROY_IF(this->auth); | |
2804 | array_destroy(this->key_types); | |
2805 | free(this); | |
2806 | } | |
2807 | ||
2808 | /** | |
2809 | * See header. | |
2810 | */ | |
2811 | enumerator_t *tls_create_private_key_enumerator(tls_version_t min_version, | |
2812 | tls_version_t max_version, | |
2813 | chunk_t hashsig, | |
2814 | identification_t *peer) | |
2815 | { | |
2816 | private_key_enumerator_t *enumerator; | |
2817 | enumerator_t *key_types; | |
2818 | ||
2819 | key_types = get_supported_key_types(min_version, max_version); | |
2820 | ||
2821 | INIT(enumerator, | |
2822 | .public = { | |
2823 | .enumerate = enumerator_enumerate_default, | |
2824 | .venumerate = _private_key_enumerate, | |
2825 | .destroy = _private_key_destroy, | |
2826 | }, | |
2827 | .key_types = create_common_key_types(key_types, hashsig), | |
2828 | .peer = peer, | |
2829 | ); | |
2830 | key_types->destroy(key_types); | |
2831 | ||
2832 | if (!array_count(enumerator->key_types)) | |
2833 | { | |
8384527f | 2834 | private_key_destroy(enumerator); |
d8e42a3d PK |
2835 | return NULL; |
2836 | } | |
2837 | return &enumerator->public; | |
2838 | } |