/src/strongswan/src/libtls/tls_server.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright (C) 2020-2021 Pascal Knecht |
3 | | * Copyright (C) 2010 Martin Willi |
4 | | * |
5 | | * Copyright (C) secunet Security Networks AG |
6 | | * |
7 | | * This program is free software; you can redistribute it and/or modify it |
8 | | * under the terms of the GNU General Public License as published by the |
9 | | * Free Software Foundation; either version 2 of the License, or (at your |
10 | | * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. |
11 | | * |
12 | | * This program is distributed in the hope that it will be useful, but |
13 | | * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
14 | | * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
15 | | * for more details. |
16 | | */ |
17 | | |
18 | | #include "tls_server.h" |
19 | | |
20 | | #include <time.h> |
21 | | |
22 | | #include <utils/debug.h> |
23 | | #include <credentials/certificates/x509.h> |
24 | | #include <collections/array.h> |
25 | | |
26 | | typedef struct private_tls_server_t private_tls_server_t; |
27 | | |
28 | | /** |
29 | | * Size of a session ID |
30 | | */ |
31 | 88 | #define SESSION_ID_SIZE 16 |
32 | | |
33 | | typedef enum { |
34 | | STATE_INIT, |
35 | | STATE_HELLO_RECEIVED, |
36 | | STATE_HELLO_SENT, |
37 | | STATE_CERT_SENT, |
38 | | STATE_KEY_EXCHANGE_SENT, |
39 | | STATE_CERTREQ_SENT, |
40 | | STATE_HELLO_DONE, |
41 | | STATE_CERT_RECEIVED, |
42 | | STATE_KEY_EXCHANGE_RECEIVED, |
43 | | STATE_CERT_VERIFY_RECEIVED, |
44 | | STATE_CIPHERSPEC_CHANGED_IN, |
45 | | STATE_FINISHED_RECEIVED, |
46 | | STATE_CIPHERSPEC_CHANGED_OUT, |
47 | | STATE_FINISHED_SENT, |
48 | | /* new states in TLS 1.3 */ |
49 | | STATE_ENCRYPTED_EXTENSIONS_SENT, |
50 | | STATE_CERT_VERIFY_SENT, |
51 | | STATE_KEY_UPDATE_REQUESTED, |
52 | | STATE_KEY_UPDATE_SENT, |
53 | | STATE_FINISHED_SENT_KEY_SWITCHED, |
54 | | } server_state_t; |
55 | | |
56 | | /** |
57 | | * Private data of an tls_server_t object. |
58 | | */ |
59 | | struct private_tls_server_t { |
60 | | |
61 | | /** |
62 | | * Public tls_server_t interface. |
63 | | */ |
64 | | tls_server_t public; |
65 | | |
66 | | /** |
67 | | * TLS stack |
68 | | */ |
69 | | tls_t *tls; |
70 | | |
71 | | /** |
72 | | * TLS crypto context |
73 | | */ |
74 | | tls_crypto_t *crypto; |
75 | | |
76 | | /** |
77 | | * TLS alert handler |
78 | | */ |
79 | | tls_alert_t *alert; |
80 | | |
81 | | /** |
82 | | * Server identity |
83 | | */ |
84 | | identification_t *server; |
85 | | |
86 | | /** |
87 | | * Peer identity, NULL for no client authentication |
88 | | */ |
89 | | identification_t *peer; |
90 | | |
91 | | /** |
92 | | * State we are in |
93 | | */ |
94 | | server_state_t state; |
95 | | |
96 | | /** |
97 | | * Hello random data selected by client |
98 | | */ |
99 | | char client_random[32]; |
100 | | |
101 | | /** |
102 | | * Hello random data selected by server |
103 | | */ |
104 | | char server_random[32]; |
105 | | |
106 | | /** |
107 | | * Auth helper for peer authentication |
108 | | */ |
109 | | auth_cfg_t *peer_auth; |
110 | | |
111 | | /** |
112 | | * Auth helper for server authentication |
113 | | */ |
114 | | auth_cfg_t *server_auth; |
115 | | |
116 | | /** |
117 | | * Peer private key |
118 | | */ |
119 | | private_key_t *private; |
120 | | |
121 | | /** |
122 | | * DHE exchange |
123 | | */ |
124 | | key_exchange_t *dh; |
125 | | |
126 | | /** |
127 | | * Requested DH group |
128 | | */ |
129 | | tls_named_group_t requested_curve; |
130 | | |
131 | | /** |
132 | | * Selected TLS cipher suite |
133 | | */ |
134 | | tls_cipher_suite_t suite; |
135 | | |
136 | | /** |
137 | | * Offered TLS version of the client |
138 | | */ |
139 | | tls_version_t client_version; |
140 | | |
141 | | /** |
142 | | * TLS session identifier |
143 | | */ |
144 | | chunk_t session; |
145 | | |
146 | | /** |
147 | | * Do we resume a session? |
148 | | */ |
149 | | bool resume; |
150 | | |
151 | | /** |
152 | | * Hash and signature algorithms supported by peer |
153 | | */ |
154 | | chunk_t hashsig; |
155 | | |
156 | | /** |
157 | | * Elliptic curves supported by peer |
158 | | */ |
159 | | chunk_t curves; |
160 | | |
161 | | /** |
162 | | * Did we receive the curves from the client? |
163 | | */ |
164 | | bool curves_received; |
165 | | |
166 | | /** |
167 | | * Whether to include CAs in CertificateRequest messages |
168 | | */ |
169 | | bool send_certreq_authorities; |
170 | | }; |
171 | | |
172 | | /** |
173 | | * Find a trusted public key to encrypt/verify key exchange data |
174 | | */ |
175 | | public_key_t *tls_find_public_key(auth_cfg_t *peer_auth, identification_t *id) |
176 | 88 | { |
177 | 88 | public_key_t *public = NULL, *current; |
178 | 88 | certificate_t *cert, *found; |
179 | 88 | key_type_t key_type = KEY_ANY; |
180 | 88 | enumerator_t *enumerator; |
181 | 88 | auth_cfg_t *auth; |
182 | | |
183 | 88 | cert = peer_auth->get(peer_auth, AUTH_HELPER_SUBJECT_CERT); |
184 | 88 | if (cert) |
185 | 45 | { |
186 | 45 | current = cert->get_public_key(cert); |
187 | 45 | if (current) |
188 | 45 | { |
189 | 45 | key_type = current->get_type(current); |
190 | 45 | current->destroy(current); |
191 | 45 | } |
192 | 45 | enumerator = lib->credmgr->create_public_enumerator(lib->credmgr, |
193 | 45 | key_type, id, peer_auth, TRUE); |
194 | 45 | while (enumerator->enumerate(enumerator, ¤t, &auth)) |
195 | 0 | { |
196 | 0 | found = auth->get(auth, AUTH_RULE_SUBJECT_CERT); |
197 | 0 | if (found && cert->equals(cert, found)) |
198 | 0 | { |
199 | 0 | public = current->get_ref(current); |
200 | 0 | peer_auth->merge(peer_auth, auth, FALSE); |
201 | 0 | break; |
202 | 0 | } |
203 | 0 | } |
204 | 45 | enumerator->destroy(enumerator); |
205 | 45 | } |
206 | 88 | return public; |
207 | 88 | } |
208 | | |
209 | | /** |
210 | | * Find a cipher suite and a server key |
211 | | */ |
212 | | static bool select_suite_and_key(private_tls_server_t *this, |
213 | | tls_cipher_suite_t *suites, int count) |
214 | 147 | { |
215 | 147 | tls_version_t version_min, version_max; |
216 | 147 | private_key_t *key; |
217 | 147 | auth_cfg_t *auth; |
218 | 147 | enumerator_t *enumerator; |
219 | | |
220 | 147 | version_min = this->tls->get_version_min(this->tls); |
221 | 147 | version_max = this->tls->get_version_max(this->tls); |
222 | 147 | enumerator = tls_create_private_key_enumerator(version_min, version_max, |
223 | 147 | this->hashsig, this->server); |
224 | 147 | if (!enumerator) |
225 | 7 | { |
226 | 7 | DBG1(DBG_TLS, "no common signature algorithms found"); |
227 | 7 | return FALSE; |
228 | 7 | } |
229 | 140 | if (!enumerator->enumerate(enumerator, &key, &auth)) |
230 | 17 | { |
231 | 17 | DBG1(DBG_TLS, "no usable TLS server certificate found for '%Y'", |
232 | 17 | this->server); |
233 | 17 | enumerator->destroy(enumerator); |
234 | 17 | return FALSE; |
235 | 17 | } |
236 | | |
237 | 123 | if (version_max >= TLS_1_3) |
238 | 28 | { |
239 | 28 | this->suite = this->crypto->select_cipher_suite(this->crypto, suites, |
240 | 28 | count, KEY_ANY); |
241 | 28 | } |
242 | 95 | else |
243 | 95 | { |
244 | 95 | this->suite = this->crypto->select_cipher_suite(this->crypto, suites, |
245 | 95 | count, key->get_type(key)); |
246 | 95 | while (!this->suite && |
247 | 7 | enumerator->enumerate(enumerator, &key, &auth)) |
248 | 0 | { /* find a key and cipher suite for one of the remaining key types */ |
249 | 0 | this->suite = this->crypto->select_cipher_suite(this->crypto, |
250 | 0 | suites, count, |
251 | 0 | key->get_type(key)); |
252 | 0 | } |
253 | 95 | } |
254 | 123 | if (!this->suite) |
255 | 35 | { |
256 | 35 | DBG1(DBG_TLS, "received cipher suites or signature schemes unacceptable"); |
257 | 35 | enumerator->destroy(enumerator); |
258 | 35 | return FALSE; |
259 | 35 | } |
260 | 88 | DBG1(DBG_TLS, "using key of type %N", key_type_names, key->get_type(key)); |
261 | 88 | DESTROY_IF(this->private); |
262 | 88 | this->private = key->get_ref(key); |
263 | 88 | this->server_auth->purge(this->server_auth, FALSE); |
264 | 88 | this->server_auth->merge(this->server_auth, auth, FALSE); |
265 | 88 | enumerator->destroy(enumerator); |
266 | 88 | return TRUE; |
267 | 123 | } |
268 | | |
269 | | /** |
270 | | * Check if the peer supports a given TLS curve |
271 | | */ |
272 | | static bool peer_supports_curve(private_tls_server_t *this, |
273 | | tls_named_group_t curve) |
274 | 377 | { |
275 | 377 | bio_reader_t *reader; |
276 | 377 | uint16_t current; |
277 | | |
278 | 377 | if (!this->curves_received) |
279 | 13 | { /* none received, assume yes */ |
280 | 13 | return TRUE; |
281 | 13 | } |
282 | 364 | reader = bio_reader_create(this->curves); |
283 | 2.96k | while (reader->remaining(reader) && reader->read_uint16(reader, ¤t)) |
284 | 2.66k | { |
285 | 2.66k | if (current == curve) |
286 | 63 | { |
287 | 63 | reader->destroy(reader); |
288 | 63 | return TRUE; |
289 | 63 | } |
290 | 2.66k | } |
291 | 301 | reader->destroy(reader); |
292 | 301 | return FALSE; |
293 | 364 | } |
294 | | |
295 | | /** |
296 | | * TLS 1.3 key exchange key share |
297 | | */ |
298 | | typedef struct { |
299 | | uint16_t curve; |
300 | | chunk_t key_share; |
301 | | } key_share_t; |
302 | | |
303 | | /** |
304 | | * Check if peer sent a key share of a given TLS named DH group |
305 | | */ |
306 | | static bool peer_offered_curve(array_t *key_shares, tls_named_group_t curve, |
307 | | key_share_t *out) |
308 | 0 | { |
309 | 0 | key_share_t peer; |
310 | 0 | int i; |
311 | |
|
312 | 0 | for (i = 0; i < array_count(key_shares); i++) |
313 | 0 | { |
314 | 0 | array_get(key_shares, i, &peer); |
315 | 0 | if (curve == peer.curve) |
316 | 0 | { |
317 | 0 | if (out) |
318 | 0 | { |
319 | 0 | *out = peer; |
320 | 0 | } |
321 | 0 | return TRUE; |
322 | 0 | } |
323 | 0 | } |
324 | 0 | return FALSE; |
325 | 0 | } |
326 | | |
327 | | /** |
328 | | * Check if client is currently retrying to connect to the server. |
329 | | */ |
330 | | static bool retrying(private_tls_server_t *this) |
331 | 90 | { |
332 | 90 | return this->state == STATE_INIT && this->requested_curve; |
333 | 90 | } |
334 | | |
335 | | /** |
336 | | * Process client hello message |
337 | | */ |
338 | | static status_t process_client_hello(private_tls_server_t *this, |
339 | | bio_reader_t *reader) |
340 | 310 | { |
341 | 310 | uint16_t legacy_version = 0, version = 0, extension_type = 0; |
342 | 310 | chunk_t random, session, ciphers, versions = chunk_empty, compression; |
343 | 310 | chunk_t ext = chunk_empty, key_shares = chunk_empty; |
344 | 310 | key_share_t peer = {0}; |
345 | 310 | chunk_t extension_data = chunk_empty; |
346 | 310 | bio_reader_t *extensions, *extension; |
347 | 310 | tls_version_t original_version_max; |
348 | 310 | int count, i; |
349 | 310 | rng_t *rng; |
350 | | |
351 | 310 | this->crypto->append_handshake(this->crypto, |
352 | 310 | TLS_CLIENT_HELLO, reader->peek(reader)); |
353 | | |
354 | 310 | if (!reader->read_uint16(reader, &legacy_version) || |
355 | 308 | !reader->read_data(reader, sizeof(this->client_random), &random) || |
356 | 303 | !reader->read_data8(reader, &session) || |
357 | 298 | !reader->read_data16(reader, &ciphers) || |
358 | 283 | !reader->read_data8(reader, &compression) || |
359 | 282 | (reader->remaining(reader) && !reader->read_data16(reader, &ext))) |
360 | 36 | { |
361 | 36 | DBG1(DBG_TLS, "received invalid ClientHello"); |
362 | 36 | this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR); |
363 | 36 | return NEED_MORE; |
364 | 36 | } |
365 | | |
366 | | /* before we do anything version-related, determine our supported suites |
367 | | * as that might change the min./max. versions */ |
368 | 274 | this->crypto->get_cipher_suites(this->crypto, NULL); |
369 | | |
370 | 274 | extensions = bio_reader_create(ext); |
371 | 2.18k | while (extensions->remaining(extensions)) |
372 | 1.96k | { |
373 | 1.96k | if (!extensions->read_uint16(extensions, &extension_type) || |
374 | 1.96k | !extensions->read_data16(extensions, &extension_data)) |
375 | 52 | { |
376 | 52 | DBG1(DBG_TLS, "received invalid ClientHello Extensions"); |
377 | 52 | this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR); |
378 | 52 | extensions->destroy(extensions); |
379 | 52 | return NEED_MORE; |
380 | 52 | } |
381 | 1.91k | extension = bio_reader_create(extension_data); |
382 | 1.91k | DBG2(DBG_TLS, "received TLS '%N' extension", |
383 | 1.91k | tls_extension_names, extension_type); |
384 | 1.91k | DBG3(DBG_TLS, "%B", &extension_data); |
385 | 1.91k | switch (extension_type) |
386 | 1.91k | { |
387 | 250 | case TLS_EXT_SIGNATURE_ALGORITHMS: |
388 | 250 | if (!extension->read_data16(extension, &extension_data)) |
389 | 2 | { |
390 | 2 | DBG1(DBG_TLS, "invalid %N extension", |
391 | 2 | tls_extension_names, extension_type); |
392 | 2 | this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR); |
393 | 2 | extensions->destroy(extensions); |
394 | 2 | extension->destroy(extension); |
395 | 2 | return NEED_MORE; |
396 | 2 | } |
397 | 248 | chunk_free(&this->hashsig); |
398 | 248 | this->hashsig = chunk_clone(extension_data); |
399 | 248 | break; |
400 | 206 | case TLS_EXT_SUPPORTED_GROUPS: |
401 | 206 | if (!extension->read_data16(extension, &extension_data)) |
402 | 1 | { |
403 | 1 | DBG1(DBG_TLS, "invalid %N extension", |
404 | 1 | tls_extension_names, extension_type); |
405 | 1 | this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR); |
406 | 1 | extensions->destroy(extensions); |
407 | 1 | extension->destroy(extension); |
408 | 1 | return NEED_MORE; |
409 | 1 | } |
410 | 205 | chunk_free(&this->curves); |
411 | 205 | this->curves_received = TRUE; |
412 | 205 | this->curves = chunk_clone(extension_data); |
413 | 205 | break; |
414 | 67 | case TLS_EXT_SUPPORTED_VERSIONS: |
415 | 67 | if (!extension->read_data8(extension, &versions)) |
416 | 2 | { |
417 | 2 | DBG1(DBG_TLS, "invalid %N extension", |
418 | 2 | tls_extension_names, extension_type); |
419 | 2 | this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR); |
420 | 2 | extensions->destroy(extensions); |
421 | 2 | extension->destroy(extension); |
422 | 2 | return NEED_MORE; |
423 | 2 | } |
424 | 65 | break; |
425 | 65 | case TLS_EXT_KEY_SHARE: |
426 | 19 | if (!extension->read_data16(extension, &key_shares)) |
427 | 1 | { |
428 | 1 | DBG1(DBG_TLS, "invalid %N extension", |
429 | 1 | tls_extension_names, extension_type); |
430 | 1 | this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR); |
431 | 1 | extensions->destroy(extensions); |
432 | 1 | extension->destroy(extension); |
433 | 1 | return NEED_MORE; |
434 | 1 | } |
435 | 18 | break; |
436 | 1.37k | default: |
437 | 1.37k | break; |
438 | 1.91k | } |
439 | 1.91k | extension->destroy(extension); |
440 | 1.91k | } |
441 | 216 | extensions->destroy(extensions); |
442 | | |
443 | 216 | if (this->tls->get_version_max(this->tls) >= TLS_1_3 && !this->hashsig.len) |
444 | 21 | { |
445 | 21 | DBG1(DBG_TLS, "no %N extension received", tls_extension_names, |
446 | 21 | TLS_EXT_SIGNATURE_ALGORITHMS); |
447 | 21 | this->alert->add(this->alert, TLS_FATAL, TLS_MISSING_EXTENSION); |
448 | 21 | return NEED_MORE; |
449 | 21 | } |
450 | | |
451 | 195 | memcpy(this->client_random, random.ptr, sizeof(this->client_random)); |
452 | | |
453 | 195 | htoun32(&this->server_random, time(NULL)); |
454 | 195 | rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK); |
455 | 195 | if (!rng || |
456 | 195 | !rng->get_bytes(rng, sizeof(this->server_random) - 4, |
457 | 195 | this->server_random + 4)) |
458 | 0 | { |
459 | 0 | DBG1(DBG_TLS, "failed to generate server random"); |
460 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); |
461 | 0 | DESTROY_IF(rng); |
462 | 0 | return NEED_MORE; |
463 | 0 | } |
464 | 195 | rng->destroy(rng); |
465 | | |
466 | 195 | original_version_max = this->tls->get_version_max(this->tls); |
467 | | |
468 | 195 | if (versions.len) |
469 | 22 | { |
470 | 22 | bio_reader_t *client_versions; |
471 | | |
472 | 22 | client_versions = bio_reader_create(versions); |
473 | 398 | while (client_versions->read_uint16(client_versions, &version)) |
474 | 386 | { |
475 | 386 | if (this->tls->set_version(this->tls, version, version)) |
476 | 10 | { |
477 | 10 | this->client_version = version; |
478 | 10 | break; |
479 | 10 | } |
480 | 386 | } |
481 | 22 | client_versions->destroy(client_versions); |
482 | 22 | } |
483 | 173 | else |
484 | 173 | { |
485 | 173 | version = legacy_version; |
486 | 173 | if (this->tls->set_version(this->tls, version, version)) |
487 | 143 | { |
488 | 143 | this->client_version = version; |
489 | 143 | } |
490 | 173 | } |
491 | | |
492 | | /* downgrade protection (see RFC 8446, section 4.1.3) */ |
493 | 195 | if ((original_version_max == TLS_1_3 && version < TLS_1_3) || |
494 | 60 | (original_version_max == TLS_1_2 && version < TLS_1_2)) |
495 | 135 | { |
496 | 135 | chunk_t downgrade_protection = tls_downgrade_protection_tls11; |
497 | | |
498 | 135 | if (version == TLS_1_2) |
499 | 88 | { |
500 | 88 | downgrade_protection = tls_downgrade_protection_tls12; |
501 | 88 | } |
502 | 135 | memcpy(&this->server_random[24], downgrade_protection.ptr, |
503 | 135 | downgrade_protection.len); |
504 | 135 | } |
505 | | |
506 | 195 | if (!this->client_version) |
507 | 48 | { |
508 | 48 | DBG1(DBG_TLS, "proposed version %N not supported", tls_version_names, |
509 | 48 | version); |
510 | 48 | this->alert->add(this->alert, TLS_FATAL, TLS_PROTOCOL_VERSION); |
511 | 48 | return NEED_MORE; |
512 | 48 | } |
513 | | |
514 | 147 | if (this->tls->get_version_max(this->tls) < TLS_1_3) |
515 | 108 | { |
516 | 108 | this->suite = this->crypto->resume_session(this->crypto, session, |
517 | 108 | this->peer, |
518 | 108 | chunk_from_thing(this->client_random), |
519 | 108 | chunk_from_thing(this->server_random)); |
520 | 108 | } |
521 | | |
522 | 147 | if (this->suite && !retrying(this)) |
523 | 0 | { |
524 | 0 | this->session = chunk_clone(session); |
525 | 0 | this->resume = TRUE; |
526 | 0 | DBG1(DBG_TLS, "resumed %N using suite %N", |
527 | 0 | tls_version_names, this->tls->get_version_max(this->tls), |
528 | 0 | tls_cipher_suite_names, this->suite); |
529 | 0 | } |
530 | 147 | else |
531 | 147 | { |
532 | 147 | tls_cipher_suite_t original_suite = this->suite; |
533 | 147 | tls_cipher_suite_t *suites; |
534 | | |
535 | 147 | count = ciphers.len / sizeof(uint16_t); |
536 | 147 | suites = malloc(count * sizeof(tls_cipher_suite_t)); |
537 | 147 | DBG2(DBG_TLS, "received %d TLS cipher suites:", count); |
538 | 4.74k | for (i = 0; i < count; i++) |
539 | 4.59k | { |
540 | 4.59k | suites[i] = untoh16(&ciphers.ptr[i * sizeof(uint16_t)]); |
541 | 4.59k | DBG2(DBG_TLS, " %N", tls_cipher_suite_names, suites[i]); |
542 | 4.59k | } |
543 | 147 | if (!select_suite_and_key(this, suites, count)) |
544 | 59 | { |
545 | 59 | this->alert->add(this->alert, TLS_FATAL, TLS_HANDSHAKE_FAILURE); |
546 | 59 | free(suites); |
547 | 59 | return NEED_MORE; |
548 | 59 | } |
549 | 88 | free(suites); |
550 | 88 | if (retrying(this) && original_suite != this->suite) |
551 | 0 | { |
552 | 0 | DBG1(DBG_TLS, "selected %N instead of %N during retry", |
553 | 0 | tls_cipher_suite_names, this->suite, tls_cipher_suite_names, |
554 | 0 | original_suite); |
555 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_ILLEGAL_PARAMETER); |
556 | 0 | return NEED_MORE; |
557 | 0 | } |
558 | 88 | if (this->tls->get_version_max(this->tls) < TLS_1_3) |
559 | 88 | { |
560 | 88 | rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG); |
561 | 88 | if (!rng || |
562 | 88 | !rng->allocate_bytes(rng, SESSION_ID_SIZE, &this->session)) |
563 | 0 | { |
564 | 0 | DBG1(DBG_TLS, "generating TLS session identifier failed, skipped"); |
565 | 0 | } |
566 | 88 | DESTROY_IF(rng); |
567 | 88 | } |
568 | 0 | else |
569 | 0 | { |
570 | 0 | chunk_free(&this->session); |
571 | 0 | this->session = chunk_clone(session); |
572 | 0 | } |
573 | 88 | DBG1(DBG_TLS, "negotiated %N using suite %N", |
574 | 88 | tls_version_names, this->tls->get_version_max(this->tls), |
575 | 88 | tls_cipher_suite_names, this->suite); |
576 | 88 | } |
577 | | |
578 | 88 | if (this->tls->get_version_max(this->tls) >= TLS_1_3) |
579 | 0 | { |
580 | 0 | key_exchange_method_t group; |
581 | 0 | tls_named_group_t curve, requesting_curve = 0; |
582 | 0 | enumerator_t *enumerator; |
583 | 0 | array_t *peer_key_shares; |
584 | |
|
585 | 0 | peer_key_shares = array_create(sizeof(key_share_t), 1); |
586 | 0 | extension = bio_reader_create(key_shares); |
587 | 0 | while (extension->remaining(extension)) |
588 | 0 | { |
589 | 0 | if (!extension->read_uint16(extension, &peer.curve) || |
590 | 0 | !extension->read_data16(extension, &peer.key_share) || |
591 | 0 | !peer.key_share.len) |
592 | 0 | { |
593 | 0 | DBG1(DBG_TLS, "invalid %N extension", |
594 | 0 | tls_extension_names, extension_type); |
595 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR); |
596 | 0 | extension->destroy(extension); |
597 | 0 | array_destroy(peer_key_shares); |
598 | 0 | return NEED_MORE; |
599 | 0 | } |
600 | 0 | array_insert(peer_key_shares, ARRAY_TAIL, &peer); |
601 | 0 | } |
602 | 0 | extension->destroy(extension); |
603 | |
|
604 | 0 | enumerator = this->crypto->create_ec_enumerator(this->crypto); |
605 | 0 | while (enumerator->enumerate(enumerator, &group, &curve)) |
606 | 0 | { |
607 | 0 | if (!requesting_curve && |
608 | 0 | peer_supports_curve(this, curve) && |
609 | 0 | !peer_offered_curve(peer_key_shares, curve, NULL)) |
610 | 0 | { |
611 | 0 | requesting_curve = curve; |
612 | 0 | } |
613 | 0 | if (peer_supports_curve(this, curve) && |
614 | 0 | peer_offered_curve(peer_key_shares, curve, &peer)) |
615 | 0 | { |
616 | 0 | DBG1(DBG_TLS, "using key exchange %N", |
617 | 0 | tls_named_group_names, curve); |
618 | 0 | this->dh = lib->crypto->create_ke(lib->crypto, group); |
619 | 0 | break; |
620 | 0 | } |
621 | 0 | } |
622 | 0 | enumerator->destroy(enumerator); |
623 | 0 | array_destroy(peer_key_shares); |
624 | |
|
625 | 0 | if (!this->dh) |
626 | 0 | { |
627 | 0 | if (retrying(this)) |
628 | 0 | { |
629 | 0 | DBG1(DBG_TLS, "already replied with a hello retry request"); |
630 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_UNEXPECTED_MESSAGE); |
631 | 0 | return NEED_MORE; |
632 | 0 | } |
633 | | |
634 | 0 | if (!requesting_curve) |
635 | 0 | { |
636 | 0 | DBG1(DBG_TLS, "no mutual supported group in client hello"); |
637 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_ILLEGAL_PARAMETER); |
638 | 0 | return NEED_MORE; |
639 | 0 | } |
640 | 0 | this->requested_curve = requesting_curve; |
641 | |
|
642 | 0 | if (!this->crypto->hash_handshake(this->crypto, NULL)) |
643 | 0 | { |
644 | 0 | DBG1(DBG_TLS, "failed to hash handshake messages"); |
645 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); |
646 | 0 | return NEED_MORE; |
647 | 0 | } |
648 | 0 | } |
649 | 0 | else |
650 | 0 | { |
651 | 0 | if (peer.key_share.len && |
652 | 0 | peer.curve != TLS_CURVE25519 && |
653 | 0 | peer.curve != TLS_CURVE448) |
654 | 0 | { /* classic format (see RFC 8446, section 4.2.8.2) */ |
655 | 0 | if (peer.key_share.ptr[0] != TLS_ANSI_UNCOMPRESSED) |
656 | 0 | { |
657 | 0 | DBG1(DBG_TLS, "DH point format '%N' not supported", |
658 | 0 | tls_ansi_point_format_names, peer.key_share.ptr[0]); |
659 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); |
660 | 0 | return NEED_MORE; |
661 | 0 | } |
662 | 0 | peer.key_share = chunk_skip(peer.key_share, 1); |
663 | 0 | } |
664 | 0 | if (!peer.key_share.len || |
665 | 0 | !this->dh->set_public_key(this->dh, peer.key_share)) |
666 | 0 | { |
667 | 0 | DBG1(DBG_TLS, "DH key derivation failed"); |
668 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_HANDSHAKE_FAILURE); |
669 | 0 | return NEED_MORE; |
670 | 0 | } |
671 | 0 | this->requested_curve = 0; |
672 | 0 | } |
673 | 0 | } |
674 | | |
675 | 88 | this->state = STATE_HELLO_RECEIVED; |
676 | 88 | return NEED_MORE; |
677 | 88 | } |
678 | | |
679 | | /** |
680 | | * Process certificate |
681 | | */ |
682 | | static status_t process_certificate(private_tls_server_t *this, |
683 | | bio_reader_t *reader) |
684 | 0 | { |
685 | 0 | certificate_t *cert; |
686 | 0 | bio_reader_t *certs; |
687 | 0 | chunk_t data; |
688 | 0 | bool first = TRUE; |
689 | |
|
690 | 0 | this->crypto->append_handshake(this->crypto, |
691 | 0 | TLS_CERTIFICATE, reader->peek(reader)); |
692 | |
|
693 | 0 | if (this->tls->get_version_max(this->tls) > TLS_1_2) |
694 | 0 | { |
695 | 0 | if (!reader->read_data8(reader, &data)) |
696 | 0 | { |
697 | 0 | DBG1(DBG_TLS, "certificate request context invalid"); |
698 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR); |
699 | 0 | return NEED_MORE; |
700 | 0 | } |
701 | 0 | } |
702 | | |
703 | 0 | if (!reader->read_data24(reader, &data)) |
704 | 0 | { |
705 | 0 | DBG1(DBG_TLS, "certificate message header invalid"); |
706 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR); |
707 | 0 | return NEED_MORE; |
708 | 0 | } |
709 | 0 | certs = bio_reader_create(data); |
710 | 0 | if (!certs->remaining(certs)) |
711 | 0 | { |
712 | 0 | if (this->tls->get_flags(this->tls) & TLS_FLAG_CLIENT_AUTH_OPTIONAL) |
713 | 0 | { |
714 | | /* client authentication is not required so we clear the identity */ |
715 | 0 | DESTROY_IF(this->peer); |
716 | 0 | this->peer = NULL; |
717 | 0 | } |
718 | 0 | else |
719 | 0 | { |
720 | 0 | DBG1(DBG_TLS, "no certificate sent by peer"); |
721 | 0 | this->alert->add(this->alert, TLS_FATAL, |
722 | 0 | this->tls->get_version_max(this->tls) > TLS_1_2 ? |
723 | 0 | TLS_CERTIFICATE_REQUIRED : TLS_HANDSHAKE_FAILURE); |
724 | 0 | return NEED_MORE; |
725 | 0 | } |
726 | 0 | } |
727 | 0 | while (certs->remaining(certs)) |
728 | 0 | { |
729 | 0 | if (!certs->read_data24(certs, &data)) |
730 | 0 | { |
731 | 0 | DBG1(DBG_TLS, "certificate message invalid"); |
732 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR); |
733 | 0 | certs->destroy(certs); |
734 | 0 | return NEED_MORE; |
735 | 0 | } |
736 | 0 | cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_X509, |
737 | 0 | BUILD_BLOB_ASN1_DER, data, BUILD_END); |
738 | 0 | if (cert) |
739 | 0 | { |
740 | 0 | if (first) |
741 | 0 | { |
742 | 0 | this->peer_auth->add(this->peer_auth, |
743 | 0 | AUTH_HELPER_SUBJECT_CERT, cert); |
744 | 0 | DBG1(DBG_TLS, "received TLS peer certificate '%Y'", |
745 | 0 | cert->get_subject(cert)); |
746 | 0 | first = FALSE; |
747 | 0 | if (this->peer && this->peer->get_type(this->peer) == ID_ANY) |
748 | 0 | { |
749 | 0 | this->peer->destroy(this->peer); |
750 | 0 | this->peer = cert->get_subject(cert); |
751 | 0 | this->peer = this->peer->clone(this->peer); |
752 | 0 | } |
753 | 0 | } |
754 | 0 | else |
755 | 0 | { |
756 | 0 | DBG1(DBG_TLS, "received TLS intermediate certificate '%Y'", |
757 | 0 | cert->get_subject(cert)); |
758 | 0 | this->peer_auth->add(this->peer_auth, AUTH_HELPER_IM_CERT, cert); |
759 | 0 | } |
760 | 0 | } |
761 | 0 | else |
762 | 0 | { |
763 | 0 | DBG1(DBG_TLS, "parsing TLS certificate failed, skipped"); |
764 | 0 | this->alert->add(this->alert, TLS_WARNING, TLS_BAD_CERTIFICATE); |
765 | 0 | } |
766 | 0 | if (this->tls->get_version_max(this->tls) > TLS_1_2) |
767 | 0 | { |
768 | 0 | if (!certs->read_data16(certs, &data)) |
769 | 0 | { |
770 | 0 | DBG1(DBG_TLS, "failed to read extensions of CertificateEntry"); |
771 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR); |
772 | 0 | return NEED_MORE; |
773 | 0 | } |
774 | 0 | } |
775 | 0 | } |
776 | 0 | certs->destroy(certs); |
777 | 0 | this->state = STATE_CERT_RECEIVED; |
778 | 0 | return NEED_MORE; |
779 | 0 | } |
780 | | |
781 | | /** |
782 | | * Process Client Key Exchange, using premaster encryption |
783 | | */ |
784 | | static status_t process_key_exchange_encrypted(private_tls_server_t *this, |
785 | | bio_reader_t *reader) |
786 | 0 | { |
787 | 0 | chunk_t encrypted, decrypted; |
788 | 0 | char premaster[48]; |
789 | 0 | rng_t *rng; |
790 | |
|
791 | 0 | this->crypto->append_handshake(this->crypto, |
792 | 0 | TLS_CLIENT_KEY_EXCHANGE, reader->peek(reader)); |
793 | |
|
794 | 0 | if (!reader->read_data16(reader, &encrypted)) |
795 | 0 | { |
796 | 0 | DBG1(DBG_TLS, "received invalid Client Key Exchange"); |
797 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR); |
798 | 0 | return NEED_MORE; |
799 | 0 | } |
800 | | |
801 | 0 | htoun16(premaster, this->client_version); |
802 | | /* pre-randomize premaster for failure cases */ |
803 | 0 | rng = lib->crypto->create_rng(lib->crypto, RNG_WEAK); |
804 | 0 | if (!rng || !rng->get_bytes(rng, sizeof(premaster) - 2, premaster + 2)) |
805 | 0 | { |
806 | 0 | DBG1(DBG_TLS, "failed to generate premaster secret"); |
807 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); |
808 | 0 | DESTROY_IF(rng); |
809 | 0 | return NEED_MORE; |
810 | 0 | } |
811 | 0 | rng->destroy(rng); |
812 | |
|
813 | 0 | if (this->private && |
814 | 0 | this->private->decrypt(this->private, ENCRYPT_RSA_PKCS1, NULL, |
815 | 0 | encrypted, &decrypted)) |
816 | 0 | { |
817 | 0 | if (decrypted.len == sizeof(premaster) && |
818 | 0 | untoh16(decrypted.ptr) == this->client_version) |
819 | 0 | { |
820 | 0 | memcpy(premaster + 2, decrypted.ptr + 2, sizeof(premaster) - 2); |
821 | 0 | } |
822 | 0 | else |
823 | 0 | { |
824 | 0 | DBG1(DBG_TLS, "decrypted premaster has invalid length/version"); |
825 | 0 | } |
826 | 0 | chunk_clear(&decrypted); |
827 | 0 | } |
828 | 0 | else |
829 | 0 | { |
830 | 0 | DBG1(DBG_TLS, "decrypting Client Key Exchange failed"); |
831 | 0 | } |
832 | |
|
833 | 0 | if (!this->crypto->derive_secrets(this->crypto, chunk_from_thing(premaster), |
834 | 0 | this->session, this->peer, |
835 | 0 | chunk_from_thing(this->client_random), |
836 | 0 | chunk_from_thing(this->server_random))) |
837 | 0 | { |
838 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); |
839 | 0 | return NEED_MORE; |
840 | 0 | } |
841 | | |
842 | 0 | this->state = STATE_KEY_EXCHANGE_RECEIVED; |
843 | 0 | return NEED_MORE; |
844 | 0 | } |
845 | | |
846 | | /** |
847 | | * Process client key exchange, using DHE exchange |
848 | | */ |
849 | | static status_t process_key_exchange_dhe(private_tls_server_t *this, |
850 | | bio_reader_t *reader) |
851 | 0 | { |
852 | 0 | chunk_t premaster, pub; |
853 | 0 | key_exchange_method_t group; |
854 | 0 | bool ec; |
855 | |
|
856 | 0 | this->crypto->append_handshake(this->crypto, |
857 | 0 | TLS_CLIENT_KEY_EXCHANGE, reader->peek(reader)); |
858 | |
|
859 | 0 | group = this->dh->get_method(this->dh); |
860 | 0 | ec = key_exchange_is_ecdh(group); |
861 | 0 | if ((ec && !reader->read_data8(reader, &pub)) || |
862 | 0 | (!ec && !reader->read_data16(reader, &pub)) || pub.len == 0) |
863 | 0 | { |
864 | 0 | DBG1(DBG_TLS, "received invalid Client Key Exchange"); |
865 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR); |
866 | 0 | return NEED_MORE; |
867 | 0 | } |
868 | | |
869 | 0 | if (ec && |
870 | 0 | group != CURVE_25519 && |
871 | 0 | group != CURVE_448) |
872 | 0 | { |
873 | 0 | if (pub.ptr[0] != TLS_ANSI_UNCOMPRESSED) |
874 | 0 | { |
875 | 0 | DBG1(DBG_TLS, "DH point format '%N' not supported", |
876 | 0 | tls_ansi_point_format_names, pub.ptr[0]); |
877 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); |
878 | 0 | return NEED_MORE; |
879 | 0 | } |
880 | 0 | pub = chunk_skip(pub, 1); |
881 | 0 | } |
882 | 0 | if (!this->dh->set_public_key(this->dh, pub)) |
883 | 0 | { |
884 | 0 | DBG1(DBG_TLS, "applying DH public value failed"); |
885 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); |
886 | 0 | return NEED_MORE; |
887 | 0 | } |
888 | 0 | if (!this->dh->get_shared_secret(this->dh, &premaster)) |
889 | 0 | { |
890 | 0 | DBG1(DBG_TLS, "calculating premaster from DH failed"); |
891 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); |
892 | 0 | return NEED_MORE; |
893 | 0 | } |
894 | | |
895 | 0 | if (!this->crypto->derive_secrets(this->crypto, premaster, |
896 | 0 | this->session, this->peer, |
897 | 0 | chunk_from_thing(this->client_random), |
898 | 0 | chunk_from_thing(this->server_random))) |
899 | 0 | { |
900 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); |
901 | 0 | chunk_clear(&premaster); |
902 | 0 | return NEED_MORE; |
903 | 0 | } |
904 | 0 | chunk_clear(&premaster); |
905 | |
|
906 | 0 | this->state = STATE_KEY_EXCHANGE_RECEIVED; |
907 | 0 | return NEED_MORE; |
908 | 0 | } |
909 | | |
910 | | /** |
911 | | * Process Client Key Exchange |
912 | | */ |
913 | | static status_t process_key_exchange(private_tls_server_t *this, |
914 | | bio_reader_t *reader) |
915 | 0 | { |
916 | 0 | if (this->dh) |
917 | 0 | { |
918 | 0 | return process_key_exchange_dhe(this, reader); |
919 | 0 | } |
920 | 0 | return process_key_exchange_encrypted(this, reader); |
921 | 0 | } |
922 | | |
923 | | /** |
924 | | * Process Certificate verify |
925 | | */ |
926 | | static status_t process_cert_verify(private_tls_server_t *this, |
927 | | bio_reader_t *reader) |
928 | 0 | { |
929 | 0 | public_key_t *public; |
930 | 0 | chunk_t msg; |
931 | |
|
932 | 0 | public = tls_find_public_key(this->peer_auth, this->peer); |
933 | 0 | if (!public) |
934 | 0 | { |
935 | 0 | DBG1(DBG_TLS, "no trusted certificate found for '%Y' to verify TLS peer", |
936 | 0 | this->peer); |
937 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_CERTIFICATE_UNKNOWN); |
938 | 0 | return NEED_MORE; |
939 | 0 | } |
940 | | |
941 | 0 | msg = reader->peek(reader); |
942 | 0 | if (!this->crypto->verify_handshake(this->crypto, public, reader)) |
943 | 0 | { |
944 | 0 | public->destroy(public); |
945 | 0 | DBG1(DBG_TLS, "signature verification failed"); |
946 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_DECRYPT_ERROR); |
947 | 0 | return NEED_MORE; |
948 | 0 | } |
949 | 0 | public->destroy(public); |
950 | 0 | this->state = STATE_CERT_VERIFY_RECEIVED; |
951 | 0 | this->crypto->append_handshake(this->crypto, TLS_CERTIFICATE_VERIFY, msg); |
952 | 0 | return NEED_MORE; |
953 | 0 | } |
954 | | |
955 | | /** |
956 | | * Process finished message |
957 | | */ |
958 | | static status_t process_finished(private_tls_server_t *this, |
959 | | bio_reader_t *reader) |
960 | 0 | { |
961 | 0 | chunk_t received, verify_data; |
962 | 0 | u_char buf[12]; |
963 | |
|
964 | 0 | if (this->tls->get_version_max(this->tls) < TLS_1_3) |
965 | 0 | { |
966 | 0 | if (!reader->read_data(reader, sizeof(buf), &received)) |
967 | 0 | { |
968 | 0 | DBG1(DBG_TLS, "received client finished too short"); |
969 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR); |
970 | 0 | return NEED_MORE; |
971 | 0 | } |
972 | 0 | if (!this->crypto->calculate_finished_legacy(this->crypto, |
973 | 0 | "client finished", buf)) |
974 | 0 | { |
975 | 0 | DBG1(DBG_TLS, "calculating client finished failed"); |
976 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); |
977 | 0 | return NEED_MORE; |
978 | 0 | } |
979 | 0 | verify_data = chunk_from_thing(buf); |
980 | 0 | } |
981 | 0 | else |
982 | 0 | { |
983 | 0 | received = reader->peek(reader); |
984 | 0 | if (!this->crypto->calculate_finished(this->crypto, FALSE, &verify_data)) |
985 | 0 | { |
986 | 0 | DBG1(DBG_TLS, "calculating client finished failed"); |
987 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); |
988 | 0 | return NEED_MORE; |
989 | 0 | } |
990 | 0 | this->crypto->change_cipher(this->crypto, TRUE); |
991 | 0 | } |
992 | | |
993 | 0 | if (!chunk_equals_const(received, verify_data)) |
994 | 0 | { |
995 | 0 | DBG1(DBG_TLS, "received client finished invalid"); |
996 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_DECRYPT_ERROR); |
997 | 0 | return NEED_MORE; |
998 | 0 | } |
999 | | |
1000 | 0 | if (verify_data.ptr != buf) |
1001 | 0 | { |
1002 | 0 | chunk_free(&verify_data); |
1003 | 0 | } |
1004 | |
|
1005 | 0 | this->crypto->append_handshake(this->crypto, TLS_FINISHED, received); |
1006 | 0 | this->state = STATE_FINISHED_RECEIVED; |
1007 | 0 | return NEED_MORE; |
1008 | 0 | } |
1009 | | |
1010 | | /** |
1011 | | * Process KeyUpdate message |
1012 | | */ |
1013 | | static status_t process_key_update(private_tls_server_t *this, |
1014 | | bio_reader_t *reader) |
1015 | 0 | { |
1016 | 0 | uint8_t update_requested; |
1017 | |
|
1018 | 0 | if (!reader->read_uint8(reader, &update_requested) || |
1019 | 0 | update_requested > 1) |
1020 | 0 | { |
1021 | 0 | DBG1(DBG_TLS, "received invalid KeyUpdate"); |
1022 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_DECODE_ERROR); |
1023 | 0 | return NEED_MORE; |
1024 | 0 | } |
1025 | | |
1026 | 0 | if (!this->crypto->update_app_keys(this->crypto, TRUE)) |
1027 | 0 | { |
1028 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); |
1029 | 0 | return NEED_MORE; |
1030 | 0 | } |
1031 | 0 | this->crypto->change_cipher(this->crypto, TRUE); |
1032 | |
|
1033 | 0 | if (update_requested) |
1034 | 0 | { |
1035 | 0 | DBG1(DBG_TLS, "client requested KeyUpdate"); |
1036 | 0 | this->state = STATE_KEY_UPDATE_REQUESTED; |
1037 | 0 | } |
1038 | 0 | return NEED_MORE; |
1039 | 0 | } |
1040 | | |
1041 | | METHOD(tls_handshake_t, process, status_t, |
1042 | | private_tls_server_t *this, tls_handshake_type_t type, bio_reader_t *reader) |
1043 | 332 | { |
1044 | 332 | tls_handshake_type_t expected DBG_UNUSED; |
1045 | | |
1046 | 332 | if (this->tls->get_version_max(this->tls) < TLS_1_3) |
1047 | 2 | { |
1048 | 2 | switch (this->state) |
1049 | 2 | { |
1050 | 0 | case STATE_INIT: |
1051 | 0 | if (type == TLS_CLIENT_HELLO) |
1052 | 0 | { |
1053 | 0 | return process_client_hello(this, reader); |
1054 | 0 | } |
1055 | 0 | expected = TLS_CLIENT_HELLO; |
1056 | 0 | break; |
1057 | 0 | case STATE_HELLO_DONE: |
1058 | 0 | if (type == TLS_CERTIFICATE) |
1059 | 0 | { |
1060 | 0 | return process_certificate(this, reader); |
1061 | 0 | } |
1062 | 0 | if (this->peer) |
1063 | 0 | { |
1064 | 0 | expected = TLS_CERTIFICATE; |
1065 | 0 | break; |
1066 | 0 | } |
1067 | | /* otherwise fall through to next state */ |
1068 | 0 | case STATE_CERT_RECEIVED: |
1069 | 0 | if (type == TLS_CLIENT_KEY_EXCHANGE) |
1070 | 0 | { |
1071 | 0 | return process_key_exchange(this, reader); |
1072 | 0 | } |
1073 | 0 | expected = TLS_CLIENT_KEY_EXCHANGE; |
1074 | 0 | break; |
1075 | 0 | case STATE_KEY_EXCHANGE_RECEIVED: |
1076 | 0 | if (type == TLS_CERTIFICATE_VERIFY) |
1077 | 0 | { |
1078 | 0 | return process_cert_verify(this, reader); |
1079 | 0 | } |
1080 | 0 | if (this->peer) |
1081 | 0 | { |
1082 | 0 | expected = TLS_CERTIFICATE_VERIFY; |
1083 | 0 | break; |
1084 | 0 | } |
1085 | 0 | return INVALID_STATE; |
1086 | 0 | case STATE_CIPHERSPEC_CHANGED_IN: |
1087 | 0 | if (type == TLS_FINISHED) |
1088 | 0 | { |
1089 | 0 | return process_finished(this, reader); |
1090 | 0 | } |
1091 | 0 | expected = TLS_FINISHED; |
1092 | 0 | break; |
1093 | 2 | default: |
1094 | 2 | DBG1(DBG_TLS, "TLS %N not expected in current state", |
1095 | 2 | tls_handshake_type_names, type); |
1096 | 2 | this->alert->add(this->alert, TLS_FATAL, TLS_UNEXPECTED_MESSAGE); |
1097 | 2 | return NEED_MORE; |
1098 | 2 | } |
1099 | 2 | } |
1100 | 330 | else |
1101 | 330 | { |
1102 | 330 | switch (this->state) |
1103 | 330 | { |
1104 | 330 | case STATE_INIT: |
1105 | 330 | if (type == TLS_CLIENT_HELLO) |
1106 | 310 | { |
1107 | 310 | return process_client_hello(this, reader); |
1108 | 310 | } |
1109 | 20 | expected = TLS_CLIENT_HELLO; |
1110 | 20 | break; |
1111 | 0 | case STATE_CIPHERSPEC_CHANGED_IN: |
1112 | 0 | case STATE_FINISHED_SENT: |
1113 | 0 | case STATE_FINISHED_SENT_KEY_SWITCHED: |
1114 | 0 | if (type == TLS_CERTIFICATE) |
1115 | 0 | { |
1116 | 0 | return process_certificate(this, reader); |
1117 | 0 | } |
1118 | 0 | if (this->peer) |
1119 | 0 | { |
1120 | 0 | expected = TLS_CERTIFICATE; |
1121 | 0 | break; |
1122 | 0 | } |
1123 | | /* otherwise fall through to next state */ |
1124 | 0 | case STATE_CERT_RECEIVED: |
1125 | 0 | if (type == TLS_CERTIFICATE_VERIFY) |
1126 | 0 | { |
1127 | 0 | return process_cert_verify(this, reader); |
1128 | 0 | } |
1129 | 0 | if (this->peer) |
1130 | 0 | { |
1131 | 0 | expected = TLS_CERTIFICATE_VERIFY; |
1132 | 0 | break; |
1133 | 0 | } |
1134 | | /* otherwise fall through to next state */ |
1135 | 0 | case STATE_CERT_VERIFY_RECEIVED: |
1136 | 0 | if (type == TLS_FINISHED) |
1137 | 0 | { |
1138 | 0 | return process_finished(this, reader); |
1139 | 0 | } |
1140 | 0 | return NEED_MORE; |
1141 | 0 | case STATE_FINISHED_RECEIVED: |
1142 | 0 | if (type == TLS_KEY_UPDATE) |
1143 | 0 | { |
1144 | 0 | return process_key_update(this, reader); |
1145 | 0 | } |
1146 | 0 | return INVALID_STATE; |
1147 | 0 | default: |
1148 | 0 | DBG1(DBG_TLS, "TLS %N not expected in current state", |
1149 | 0 | tls_handshake_type_names, type); |
1150 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_UNEXPECTED_MESSAGE); |
1151 | 0 | return NEED_MORE; |
1152 | 330 | } |
1153 | 330 | } |
1154 | 20 | DBG1(DBG_TLS, "TLS %N expected, but received %N", |
1155 | 20 | tls_handshake_type_names, expected, tls_handshake_type_names, type); |
1156 | 20 | this->alert->add(this->alert, TLS_FATAL, TLS_UNEXPECTED_MESSAGE); |
1157 | 20 | return NEED_MORE; |
1158 | 332 | } |
1159 | | |
1160 | | /** |
1161 | | * Write public key into key share extension |
1162 | | */ |
1163 | | bool tls_write_key_share(bio_writer_t **key_share, key_exchange_t *dh) |
1164 | 2.71k | { |
1165 | 2.71k | bio_writer_t *writer; |
1166 | 2.71k | tls_named_group_t curve; |
1167 | 2.71k | chunk_t pub; |
1168 | | |
1169 | 2.71k | if (!dh) |
1170 | 0 | { |
1171 | 0 | return FALSE; |
1172 | 0 | } |
1173 | 2.71k | curve = tls_ec_group_to_curve(dh->get_method(dh)); |
1174 | 2.71k | if (!curve || !dh->get_public_key(dh, &pub)) |
1175 | 0 | { |
1176 | 0 | return FALSE; |
1177 | 0 | } |
1178 | 2.71k | *key_share = writer = bio_writer_create(pub.len + 7); |
1179 | 2.71k | writer->write_uint16(writer, curve); |
1180 | 2.71k | if (curve == TLS_CURVE25519 || |
1181 | 2.71k | curve == TLS_CURVE448) |
1182 | 0 | { |
1183 | 0 | writer->write_data16(writer, pub); |
1184 | 0 | } |
1185 | 2.71k | else |
1186 | 2.71k | { /* classic format (see RFC 8446, section 4.2.8.2) */ |
1187 | 2.71k | writer->write_uint16(writer, pub.len + 1); |
1188 | 2.71k | writer->write_uint8(writer, TLS_ANSI_UNCOMPRESSED); |
1189 | 2.71k | writer->write_data(writer, pub); |
1190 | 2.71k | } |
1191 | 2.71k | free(pub.ptr); |
1192 | 2.71k | return TRUE; |
1193 | 2.71k | } |
1194 | | |
1195 | | /** |
1196 | | * Send ServerHello message |
1197 | | */ |
1198 | | static status_t send_server_hello(private_tls_server_t *this, |
1199 | | tls_handshake_type_t *type, bio_writer_t *writer) |
1200 | 84 | { |
1201 | 84 | bio_writer_t *key_share, *extensions; |
1202 | 84 | tls_version_t version; |
1203 | | |
1204 | 84 | version = this->tls->get_version_max(this->tls); |
1205 | | |
1206 | | /* cap legacy version at TLS 1.2 for middlebox compatibility */ |
1207 | 84 | writer->write_uint16(writer, min(TLS_1_2, version)); |
1208 | | |
1209 | 84 | if (this->requested_curve) |
1210 | 0 | { |
1211 | 0 | writer->write_data(writer, tls_hello_retry_request_magic); |
1212 | 0 | } |
1213 | 84 | else |
1214 | 84 | { |
1215 | 84 | writer->write_data(writer, chunk_from_thing(this->server_random)); |
1216 | 84 | } |
1217 | | |
1218 | | /* session identifier if we have one */ |
1219 | 84 | writer->write_data8(writer, this->session); |
1220 | | |
1221 | | /* add selected TLS cipher suite */ |
1222 | 84 | writer->write_uint16(writer, this->suite); |
1223 | | |
1224 | | /* NULL compression only */ |
1225 | 84 | writer->write_uint8(writer, 0); |
1226 | | |
1227 | 84 | if (version >= TLS_1_3) |
1228 | 0 | { |
1229 | 0 | extensions = bio_writer_create(32); |
1230 | |
|
1231 | 0 | DBG2(DBG_TLS, "sending extension: %N", |
1232 | 0 | tls_extension_names, TLS_EXT_SUPPORTED_VERSIONS); |
1233 | 0 | extensions->write_uint16(extensions, TLS_EXT_SUPPORTED_VERSIONS); |
1234 | 0 | extensions->write_uint16(extensions, 2); |
1235 | 0 | extensions->write_uint16(extensions, version); |
1236 | |
|
1237 | 0 | DBG2(DBG_TLS, "sending extension: %N", |
1238 | 0 | tls_extension_names, TLS_EXT_KEY_SHARE); |
1239 | 0 | extensions->write_uint16(extensions, TLS_EXT_KEY_SHARE); |
1240 | 0 | if (this->requested_curve) |
1241 | 0 | { |
1242 | 0 | DBG1(DBG_TLS, "requesting key exchange with %N", |
1243 | 0 | tls_named_group_names, this->requested_curve); |
1244 | 0 | extensions->write_uint16(extensions, 2); |
1245 | 0 | extensions->write_uint16(extensions, this->requested_curve); |
1246 | 0 | } |
1247 | 0 | else |
1248 | 0 | { |
1249 | 0 | if (!tls_write_key_share(&key_share, this->dh)) |
1250 | 0 | { |
1251 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); |
1252 | 0 | extensions->destroy(extensions); |
1253 | 0 | return NEED_MORE; |
1254 | 0 | } |
1255 | 0 | extensions->write_data16(extensions, key_share->get_buf(key_share)); |
1256 | 0 | key_share->destroy(key_share); |
1257 | 0 | } |
1258 | | |
1259 | 0 | writer->write_data16(writer, extensions->get_buf(extensions)); |
1260 | 0 | extensions->destroy(extensions); |
1261 | 0 | } |
1262 | | |
1263 | 84 | *type = TLS_SERVER_HELLO; |
1264 | 84 | this->state = this->requested_curve ? STATE_INIT : STATE_HELLO_SENT; |
1265 | 84 | this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer)); |
1266 | 84 | return NEED_MORE; |
1267 | 84 | } |
1268 | | |
1269 | | /** |
1270 | | * Send encrypted extensions message |
1271 | | */ |
1272 | | static status_t send_encrypted_extensions(private_tls_server_t *this, |
1273 | | tls_handshake_type_t *type, |
1274 | | bio_writer_t *writer) |
1275 | 0 | { |
1276 | 0 | chunk_t shared_secret = chunk_empty; |
1277 | |
|
1278 | 0 | if (!this->dh->get_shared_secret(this->dh, &shared_secret) || |
1279 | 0 | !this->crypto->derive_handshake_keys(this->crypto, shared_secret)) |
1280 | 0 | { |
1281 | 0 | DBG1(DBG_TLS, "DH key derivation failed"); |
1282 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_HANDSHAKE_FAILURE); |
1283 | 0 | chunk_clear(&shared_secret); |
1284 | 0 | return NEED_MORE; |
1285 | 0 | } |
1286 | 0 | chunk_clear(&shared_secret); |
1287 | |
|
1288 | 0 | this->crypto->change_cipher(this->crypto, TRUE); |
1289 | 0 | this->crypto->change_cipher(this->crypto, FALSE); |
1290 | | |
1291 | | /* currently no extensions are supported */ |
1292 | 0 | writer->write_uint16(writer, 0); |
1293 | |
|
1294 | 0 | *type = TLS_ENCRYPTED_EXTENSIONS; |
1295 | 0 | this->state = STATE_ENCRYPTED_EXTENSIONS_SENT; |
1296 | 0 | this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer)); |
1297 | 0 | return NEED_MORE; |
1298 | 0 | } |
1299 | | |
1300 | | /** |
1301 | | * Send Certificate |
1302 | | */ |
1303 | | static status_t send_certificate(private_tls_server_t *this, |
1304 | | tls_handshake_type_t *type, bio_writer_t *writer) |
1305 | 84 | { |
1306 | 84 | enumerator_t *enumerator; |
1307 | 84 | certificate_t *cert; |
1308 | 84 | auth_rule_t rule; |
1309 | 84 | bio_writer_t *certs; |
1310 | 84 | chunk_t data; |
1311 | | |
1312 | | /* certificate request context as described in RFC 8446, section 4.4.2 */ |
1313 | 84 | if (this->tls->get_version_max(this->tls) > TLS_1_2) |
1314 | 0 | { |
1315 | 0 | writer->write_uint8(writer, 0); |
1316 | 0 | } |
1317 | | |
1318 | | /* generate certificate payload */ |
1319 | 84 | certs = bio_writer_create(256); |
1320 | 84 | cert = this->server_auth->get(this->server_auth, AUTH_RULE_SUBJECT_CERT); |
1321 | 84 | if (cert) |
1322 | 84 | { |
1323 | 84 | if (cert->get_encoding(cert, CERT_ASN1_DER, &data)) |
1324 | 84 | { |
1325 | 84 | DBG1(DBG_TLS, "sending TLS server certificate '%Y'", |
1326 | 84 | cert->get_subject(cert)); |
1327 | 84 | certs->write_data24(certs, data); |
1328 | 84 | free(data.ptr); |
1329 | | |
1330 | | /* extensions see RFC 8446, section 4.4.2 */ |
1331 | 84 | if (this->tls->get_version_max(this->tls) > TLS_1_2) |
1332 | 0 | { |
1333 | 0 | certs->write_uint16(certs, 0); |
1334 | 0 | } |
1335 | 84 | } |
1336 | 84 | } |
1337 | 84 | enumerator = this->server_auth->create_enumerator(this->server_auth); |
1338 | 168 | while (enumerator->enumerate(enumerator, &rule, &cert)) |
1339 | 84 | { |
1340 | 84 | if (rule == AUTH_RULE_IM_CERT) |
1341 | 0 | { |
1342 | 0 | if (cert->get_encoding(cert, CERT_ASN1_DER, &data)) |
1343 | 0 | { |
1344 | 0 | DBG1(DBG_TLS, "sending TLS intermediate certificate '%Y'", |
1345 | 0 | cert->get_subject(cert)); |
1346 | 0 | certs->write_data24(certs, data); |
1347 | 0 | free(data.ptr); |
1348 | | |
1349 | | /* extensions see RFC 8446, section 4.4.2 */ |
1350 | 0 | if (this->tls->get_version_max(this->tls) > TLS_1_2) |
1351 | 0 | { |
1352 | 0 | certs->write_uint16(certs, 0); |
1353 | 0 | } |
1354 | 0 | } |
1355 | 0 | } |
1356 | 84 | } |
1357 | 84 | enumerator->destroy(enumerator); |
1358 | | |
1359 | 84 | writer->write_data24(writer, certs->get_buf(certs)); |
1360 | 84 | certs->destroy(certs); |
1361 | | |
1362 | 84 | *type = TLS_CERTIFICATE; |
1363 | 84 | this->state = STATE_CERT_SENT; |
1364 | 84 | this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer)); |
1365 | 84 | return NEED_MORE; |
1366 | 84 | } |
1367 | | |
1368 | | /** |
1369 | | * Send Certificate Verify |
1370 | | */ |
1371 | | static status_t send_certificate_verify(private_tls_server_t *this, |
1372 | | tls_handshake_type_t *type, |
1373 | | bio_writer_t *writer) |
1374 | 0 | { |
1375 | 0 | if (!this->crypto->sign_handshake(this->crypto, this->private, writer, |
1376 | 0 | this->hashsig)) |
1377 | 0 | { |
1378 | 0 | DBG1(DBG_TLS, "signature generation failed"); |
1379 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); |
1380 | 0 | return NEED_MORE; |
1381 | 0 | } |
1382 | | |
1383 | 0 | *type = TLS_CERTIFICATE_VERIFY; |
1384 | 0 | this->state = STATE_CERT_VERIFY_SENT; |
1385 | 0 | this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer)); |
1386 | 0 | return NEED_MORE; |
1387 | 0 | } |
1388 | | |
1389 | | /* |
1390 | | * Write all available certificate authorities to output writer |
1391 | | */ |
1392 | | static void write_certificate_authorities(bio_writer_t *writer) |
1393 | 38 | { |
1394 | 38 | bio_writer_t *authorities; |
1395 | 38 | enumerator_t *enumerator; |
1396 | 38 | certificate_t *cert; |
1397 | 38 | x509_t *x509; |
1398 | 38 | identification_t *id; |
1399 | | |
1400 | 38 | authorities = bio_writer_create(64); |
1401 | 38 | enumerator = lib->credmgr->create_cert_enumerator(lib->credmgr, CERT_X509, |
1402 | 38 | KEY_RSA, NULL, TRUE); |
1403 | 38 | while (enumerator->enumerate(enumerator, &cert)) |
1404 | 0 | { |
1405 | 0 | x509 = (x509_t*)cert; |
1406 | 0 | if (x509->get_flags(x509) & X509_CA) |
1407 | 0 | { |
1408 | 0 | id = cert->get_subject(cert); |
1409 | 0 | DBG1(DBG_TLS, "sending TLS cert request for '%Y'", id); |
1410 | 0 | authorities->write_data16(authorities, id->get_encoding(id)); |
1411 | 0 | } |
1412 | 0 | } |
1413 | 38 | enumerator->destroy(enumerator); |
1414 | 38 | writer->write_data16(writer, authorities->get_buf(authorities)); |
1415 | 38 | authorities->destroy(authorities); |
1416 | 38 | } |
1417 | | |
1418 | | /** |
1419 | | * Send Certificate Request |
1420 | | */ |
1421 | | static status_t send_certificate_request(private_tls_server_t *this, |
1422 | | tls_handshake_type_t *type, |
1423 | | bio_writer_t *writer) |
1424 | 38 | { |
1425 | 38 | bio_writer_t *authorities, *supported, *extensions; |
1426 | | |
1427 | 38 | if (this->tls->get_version_max(this->tls) < TLS_1_3) |
1428 | 38 | { |
1429 | 38 | supported = bio_writer_create(4); |
1430 | | /* we propose both RSA and ECDSA */ |
1431 | 38 | supported->write_uint8(supported, TLS_RSA_SIGN); |
1432 | 38 | supported->write_uint8(supported, TLS_ECDSA_SIGN); |
1433 | 38 | writer->write_data8(writer, supported->get_buf(supported)); |
1434 | 38 | supported->destroy(supported); |
1435 | 38 | if (this->tls->get_version_max(this->tls) >= TLS_1_2) |
1436 | 29 | { |
1437 | 29 | this->crypto->get_signature_algorithms(this->crypto, writer, TRUE); |
1438 | 29 | } |
1439 | | |
1440 | 38 | if (this->send_certreq_authorities) |
1441 | 38 | { |
1442 | 38 | write_certificate_authorities(writer); |
1443 | 38 | } |
1444 | 0 | else |
1445 | 0 | { |
1446 | 0 | writer->write_data16(writer, chunk_empty); |
1447 | 0 | } |
1448 | 38 | } |
1449 | 0 | else |
1450 | 0 | { |
1451 | | /* certificate request context as described in RFC 8446, section 4.3.2 */ |
1452 | 0 | writer->write_uint8(writer, 0); |
1453 | |
|
1454 | 0 | extensions = bio_writer_create(32); |
1455 | |
|
1456 | 0 | if (this->send_certreq_authorities) |
1457 | 0 | { |
1458 | 0 | DBG2(DBG_TLS, "sending extension: %N", |
1459 | 0 | tls_extension_names, TLS_EXT_CERTIFICATE_AUTHORITIES); |
1460 | 0 | authorities = bio_writer_create(64); |
1461 | 0 | write_certificate_authorities(authorities); |
1462 | 0 | extensions->write_uint16(extensions, TLS_EXT_CERTIFICATE_AUTHORITIES); |
1463 | 0 | extensions->write_data16(extensions, authorities->get_buf(authorities)); |
1464 | 0 | authorities->destroy(authorities); |
1465 | 0 | } |
1466 | |
|
1467 | 0 | DBG2(DBG_TLS, "sending extension: %N", |
1468 | 0 | tls_extension_names, TLS_EXT_SIGNATURE_ALGORITHMS); |
1469 | 0 | extensions->write_uint16(extensions, TLS_EXT_SIGNATURE_ALGORITHMS); |
1470 | 0 | supported = bio_writer_create(32); |
1471 | 0 | this->crypto->get_signature_algorithms(this->crypto, supported, TRUE); |
1472 | 0 | extensions->write_data16(extensions, supported->get_buf(supported)); |
1473 | 0 | supported->destroy(supported); |
1474 | 0 | writer->write_data16(writer, extensions->get_buf(extensions)); |
1475 | 0 | extensions->destroy(extensions); |
1476 | 0 | } |
1477 | | |
1478 | 38 | *type = TLS_CERTIFICATE_REQUEST; |
1479 | 38 | this->state = STATE_CERTREQ_SENT; |
1480 | 38 | this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer)); |
1481 | 38 | return NEED_MORE; |
1482 | 38 | } |
1483 | | |
1484 | | /** |
1485 | | * Try to find a curve/group supported by both, client and server |
1486 | | */ |
1487 | | static bool find_supported_curve(private_tls_server_t *this, |
1488 | | tls_named_group_t *curve, |
1489 | | key_exchange_method_t *group) |
1490 | 63 | { |
1491 | 63 | tls_named_group_t current; |
1492 | 63 | key_exchange_method_t current_group; |
1493 | 63 | enumerator_t *enumerator; |
1494 | | |
1495 | 63 | enumerator = this->crypto->create_ec_enumerator(this->crypto); |
1496 | 301 | while (enumerator->enumerate(enumerator, ¤t_group, ¤t)) |
1497 | 293 | { |
1498 | 293 | if (peer_supports_curve(this, current)) |
1499 | 55 | { |
1500 | 55 | *curve = current; |
1501 | 55 | *group = current_group; |
1502 | 55 | enumerator->destroy(enumerator); |
1503 | 55 | return TRUE; |
1504 | 55 | } |
1505 | 293 | } |
1506 | 8 | enumerator->destroy(enumerator); |
1507 | 8 | return FALSE; |
1508 | 63 | } |
1509 | | |
1510 | | /** |
1511 | | * Send Server key Exchange |
1512 | | */ |
1513 | | static status_t send_server_key_exchange(private_tls_server_t *this, |
1514 | | tls_handshake_type_t *type, bio_writer_t *writer, |
1515 | | key_exchange_method_t group) |
1516 | 84 | { |
1517 | 84 | diffie_hellman_params_t *params = NULL; |
1518 | 84 | tls_named_group_t curve; |
1519 | 84 | chunk_t chunk; |
1520 | | |
1521 | 84 | if (key_exchange_is_ecdh(group)) |
1522 | 84 | { |
1523 | 84 | curve = tls_ec_group_to_curve(group); |
1524 | 84 | if (!curve || (!peer_supports_curve(this, curve) && |
1525 | 63 | !find_supported_curve(this, &curve, &group))) |
1526 | 8 | { |
1527 | 8 | DBG1(DBG_TLS, "no EC group supported by client and server"); |
1528 | 8 | this->alert->add(this->alert, TLS_FATAL, TLS_HANDSHAKE_FAILURE); |
1529 | 8 | return NEED_MORE; |
1530 | 8 | } |
1531 | 76 | DBG2(DBG_TLS, "selected ECDH group %N", tls_named_group_names, curve); |
1532 | 76 | writer->write_uint8(writer, TLS_ECC_NAMED_CURVE); |
1533 | 76 | writer->write_uint16(writer, curve); |
1534 | 76 | } |
1535 | 0 | else |
1536 | 0 | { |
1537 | 0 | params = diffie_hellman_get_params(group); |
1538 | 0 | if (!params) |
1539 | 0 | { |
1540 | 0 | DBG1(DBG_TLS, "no parameters found for DH group %N", |
1541 | 0 | key_exchange_method_names, group); |
1542 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); |
1543 | 0 | return NEED_MORE; |
1544 | 0 | } |
1545 | 0 | DBG2(DBG_TLS, "selected DH group %N", key_exchange_method_names, group); |
1546 | 0 | writer->write_data16(writer, params->prime); |
1547 | 0 | writer->write_data16(writer, params->generator); |
1548 | 0 | } |
1549 | 76 | this->dh = lib->crypto->create_ke(lib->crypto, group); |
1550 | 76 | if (!this->dh) |
1551 | 0 | { |
1552 | 0 | DBG1(DBG_TLS, "DH group %N not supported", |
1553 | 0 | key_exchange_method_names, group); |
1554 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); |
1555 | 0 | return NEED_MORE; |
1556 | 0 | } |
1557 | 76 | if (!this->dh->get_public_key(this->dh, &chunk)) |
1558 | 0 | { |
1559 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); |
1560 | 0 | return NEED_MORE; |
1561 | 0 | } |
1562 | 76 | if (params) |
1563 | 0 | { |
1564 | 0 | writer->write_data16(writer, chunk); |
1565 | 0 | } |
1566 | 76 | else if (group != CURVE_25519 && |
1567 | 57 | group != CURVE_448) |
1568 | 50 | { /* ECP uses 8bit length header only, but a point format */ |
1569 | 50 | writer->write_uint8(writer, chunk.len + 1); |
1570 | 50 | writer->write_uint8(writer, TLS_ANSI_UNCOMPRESSED); |
1571 | 50 | writer->write_data(writer, chunk); |
1572 | 50 | } |
1573 | 26 | else |
1574 | 26 | { /* ECPoint uses an 8-bit length header only */ |
1575 | 26 | writer->write_data8(writer, chunk); |
1576 | 26 | } |
1577 | 76 | free(chunk.ptr); |
1578 | | |
1579 | 76 | chunk = chunk_cat("ccc", chunk_from_thing(this->client_random), |
1580 | 76 | chunk_from_thing(this->server_random), writer->get_buf(writer)); |
1581 | 76 | if (!this->private || !this->crypto->sign(this->crypto, this->private, |
1582 | 76 | writer, chunk, this->hashsig)) |
1583 | 38 | { |
1584 | 38 | DBG1(DBG_TLS, "signing DH parameters failed"); |
1585 | 38 | this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); |
1586 | 38 | free(chunk.ptr); |
1587 | 38 | return NEED_MORE; |
1588 | 38 | } |
1589 | 38 | free(chunk.ptr); |
1590 | 38 | *type = TLS_SERVER_KEY_EXCHANGE; |
1591 | 38 | this->state = STATE_KEY_EXCHANGE_SENT; |
1592 | 38 | this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer)); |
1593 | 38 | return NEED_MORE; |
1594 | 76 | } |
1595 | | |
1596 | | /** |
1597 | | * Send Hello Done |
1598 | | */ |
1599 | | static status_t send_hello_done(private_tls_server_t *this, |
1600 | | tls_handshake_type_t *type, bio_writer_t *writer) |
1601 | 38 | { |
1602 | 38 | *type = TLS_SERVER_HELLO_DONE; |
1603 | 38 | this->state = STATE_HELLO_DONE; |
1604 | 38 | this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer)); |
1605 | 38 | return NEED_MORE; |
1606 | 38 | } |
1607 | | |
1608 | | /** |
1609 | | * Send Finished |
1610 | | */ |
1611 | | static status_t send_finished(private_tls_server_t *this, |
1612 | | tls_handshake_type_t *type, bio_writer_t *writer) |
1613 | 0 | { |
1614 | 0 | if (this->tls->get_version_max(this->tls) < TLS_1_3) |
1615 | 0 | { |
1616 | 0 | char buf[12]; |
1617 | |
|
1618 | 0 | if (!this->crypto->calculate_finished_legacy(this->crypto, |
1619 | 0 | "server finished", buf)) |
1620 | 0 | { |
1621 | 0 | DBG1(DBG_TLS, "calculating server finished data failed"); |
1622 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); |
1623 | 0 | return FAILED; |
1624 | 0 | } |
1625 | | |
1626 | 0 | writer->write_data(writer, chunk_from_thing(buf)); |
1627 | 0 | } |
1628 | 0 | else |
1629 | 0 | { |
1630 | 0 | chunk_t verify_data; |
1631 | |
|
1632 | 0 | if (!this->crypto->calculate_finished(this->crypto, TRUE, &verify_data)) |
1633 | 0 | { |
1634 | 0 | DBG1(DBG_TLS, "calculating server finished data failed"); |
1635 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); |
1636 | 0 | return NEED_MORE; |
1637 | 0 | } |
1638 | | |
1639 | 0 | writer->write_data(writer, verify_data); |
1640 | 0 | chunk_free(&verify_data); |
1641 | 0 | } |
1642 | | |
1643 | 0 | *type = TLS_FINISHED; |
1644 | 0 | this->state = STATE_FINISHED_SENT; |
1645 | 0 | this->crypto->append_handshake(this->crypto, *type, writer->get_buf(writer)); |
1646 | |
|
1647 | 0 | return NEED_MORE; |
1648 | 0 | } |
1649 | | |
1650 | | /** |
1651 | | * Send KeyUpdate message |
1652 | | */ |
1653 | | static status_t send_key_update(private_tls_server_t *this, |
1654 | | tls_handshake_type_t *type, bio_writer_t *writer) |
1655 | 0 | { |
1656 | 0 | *type = TLS_KEY_UPDATE; |
1657 | | |
1658 | | /* we currently only send this as reply, so we never request an update */ |
1659 | 0 | writer->write_uint8(writer, 0); |
1660 | |
|
1661 | 0 | this->state = STATE_KEY_UPDATE_SENT; |
1662 | 0 | return NEED_MORE; |
1663 | 0 | } |
1664 | | |
1665 | | METHOD(tls_handshake_t, build, status_t, |
1666 | | private_tls_server_t *this, tls_handshake_type_t *type, bio_writer_t *writer) |
1667 | 506 | { |
1668 | 506 | key_exchange_method_t group; |
1669 | | |
1670 | 506 | if (this->tls->get_version_max(this->tls) < TLS_1_3) |
1671 | 404 | { |
1672 | 404 | switch (this->state) |
1673 | 404 | { |
1674 | 84 | case STATE_HELLO_RECEIVED: |
1675 | 84 | return send_server_hello(this, type, writer); |
1676 | 84 | case STATE_HELLO_SENT: |
1677 | 84 | return send_certificate(this, type, writer); |
1678 | 84 | case STATE_CERT_SENT: |
1679 | 84 | group = this->crypto->get_dh_group(this->crypto); |
1680 | 84 | if (group) |
1681 | 84 | { |
1682 | 84 | return send_server_key_exchange(this, type, writer, group); |
1683 | 84 | } |
1684 | | /* otherwise fall through to next state */ |
1685 | 38 | case STATE_KEY_EXCHANGE_SENT: |
1686 | 38 | if (this->peer) |
1687 | 38 | { |
1688 | 38 | return send_certificate_request(this, type, writer); |
1689 | 38 | } |
1690 | | /* otherwise fall through to next state */ |
1691 | 38 | case STATE_CERTREQ_SENT: |
1692 | 38 | return send_hello_done(this, type, writer); |
1693 | 0 | case STATE_CIPHERSPEC_CHANGED_OUT: |
1694 | 0 | return send_finished(this, type, writer); |
1695 | 0 | case STATE_FINISHED_SENT: |
1696 | 0 | return INVALID_STATE; |
1697 | 76 | default: |
1698 | 76 | return INVALID_STATE; |
1699 | 404 | } |
1700 | 404 | } |
1701 | 102 | else |
1702 | 102 | { |
1703 | 102 | switch (this->state) |
1704 | 102 | { |
1705 | 0 | case STATE_HELLO_RECEIVED: |
1706 | 0 | return send_server_hello(this, type, writer); |
1707 | 0 | case STATE_HELLO_SENT: |
1708 | 0 | case STATE_CIPHERSPEC_CHANGED_OUT: |
1709 | 0 | return send_encrypted_extensions(this, type, writer); |
1710 | 0 | case STATE_ENCRYPTED_EXTENSIONS_SENT: |
1711 | 0 | if (this->peer) |
1712 | 0 | { |
1713 | 0 | return send_certificate_request(this, type, writer); |
1714 | 0 | } |
1715 | | /* otherwise fall through to next state */ |
1716 | 0 | case STATE_CERTREQ_SENT: |
1717 | 0 | return send_certificate(this, type, writer); |
1718 | 0 | case STATE_CERT_SENT: |
1719 | 0 | return send_certificate_verify(this, type, writer); |
1720 | 0 | case STATE_CERT_VERIFY_SENT: |
1721 | 0 | return send_finished(this, type, writer); |
1722 | 0 | case STATE_FINISHED_SENT: |
1723 | 0 | if (!this->crypto->derive_app_keys(this->crypto)) |
1724 | 0 | { |
1725 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); |
1726 | 0 | return NEED_MORE; |
1727 | 0 | } |
1728 | | /* inbound key switches after process client finished message */ |
1729 | 0 | this->crypto->change_cipher(this->crypto, FALSE); |
1730 | 0 | this->state = STATE_FINISHED_SENT_KEY_SWITCHED; |
1731 | 0 | return INVALID_STATE; |
1732 | 0 | case STATE_KEY_UPDATE_REQUESTED: |
1733 | 0 | return send_key_update(this, type, writer); |
1734 | 0 | case STATE_KEY_UPDATE_SENT: |
1735 | 0 | if (!this->crypto->update_app_keys(this->crypto, FALSE)) |
1736 | 0 | { |
1737 | 0 | this->alert->add(this->alert, TLS_FATAL, TLS_INTERNAL_ERROR); |
1738 | 0 | return NEED_MORE; |
1739 | 0 | } |
1740 | 0 | this->crypto->change_cipher(this->crypto, FALSE); |
1741 | 0 | this->state = STATE_FINISHED_RECEIVED; |
1742 | 102 | default: |
1743 | 102 | return INVALID_STATE; |
1744 | 102 | } |
1745 | 102 | } |
1746 | 506 | } |
1747 | | |
1748 | | METHOD(tls_handshake_t, cipherspec_changed, bool, |
1749 | | private_tls_server_t *this, bool inbound) |
1750 | 509 | { |
1751 | 509 | if (this->tls->get_version_max(this->tls) < TLS_1_3) |
1752 | 405 | { |
1753 | 405 | if (inbound) |
1754 | 1 | { |
1755 | 1 | if (this->resume) |
1756 | 0 | { |
1757 | 0 | return this->state == STATE_FINISHED_SENT; |
1758 | 0 | } |
1759 | 1 | if (this->peer) |
1760 | 1 | { |
1761 | 1 | return this->state == STATE_CERT_VERIFY_RECEIVED; |
1762 | 1 | } |
1763 | 0 | return this->state == STATE_KEY_EXCHANGE_RECEIVED; |
1764 | 1 | } |
1765 | 404 | else |
1766 | 404 | { |
1767 | 404 | if (this->resume) |
1768 | 0 | { |
1769 | 0 | return this->state == STATE_HELLO_SENT; |
1770 | 0 | } |
1771 | 404 | return this->state == STATE_FINISHED_RECEIVED; |
1772 | 404 | } |
1773 | 0 | return FALSE; |
1774 | 405 | } |
1775 | 104 | else |
1776 | 104 | { |
1777 | 104 | if (inbound) |
1778 | 2 | { /* accept ChangeCipherSpec after ServerFinish or HelloRetryRequest */ |
1779 | 2 | return this->state == STATE_FINISHED_SENT || |
1780 | 2 | this->state == STATE_FINISHED_SENT_KEY_SWITCHED || |
1781 | 2 | retrying(this); |
1782 | 2 | } |
1783 | 102 | else |
1784 | 102 | { |
1785 | 102 | return this->state == STATE_HELLO_SENT; |
1786 | 102 | } |
1787 | 104 | } |
1788 | 509 | } |
1789 | | |
1790 | | METHOD(tls_handshake_t, change_cipherspec, void, |
1791 | | private_tls_server_t *this, bool inbound) |
1792 | 0 | { |
1793 | 0 | if (this->tls->get_version_max(this->tls) < TLS_1_3) |
1794 | 0 | { |
1795 | 0 | this->crypto->change_cipher(this->crypto, inbound); |
1796 | 0 | } |
1797 | |
|
1798 | 0 | if (retrying(this)) |
1799 | 0 | { /* client might send a ChangeCipherSpec after a HelloRetryRequest and |
1800 | | * before a new ClientHello which should not cause any state changes */ |
1801 | 0 | return; |
1802 | 0 | } |
1803 | | |
1804 | 0 | if (inbound) |
1805 | 0 | { |
1806 | 0 | this->state = STATE_CIPHERSPEC_CHANGED_IN; |
1807 | 0 | } |
1808 | 0 | else |
1809 | 0 | { |
1810 | 0 | this->state = STATE_CIPHERSPEC_CHANGED_OUT; |
1811 | 0 | } |
1812 | 0 | } |
1813 | | |
1814 | | METHOD(tls_handshake_t, finished, bool, |
1815 | | private_tls_server_t *this) |
1816 | 1.13k | { |
1817 | 1.13k | if (this->tls->get_version_max(this->tls) < TLS_1_3) |
1818 | 406 | { |
1819 | 406 | if (this->resume) |
1820 | 0 | { |
1821 | 0 | return this->state == STATE_FINISHED_RECEIVED; |
1822 | 0 | } |
1823 | 406 | return this->state == STATE_FINISHED_SENT; |
1824 | 406 | } |
1825 | 725 | else |
1826 | 725 | { |
1827 | 725 | return this->state == STATE_FINISHED_RECEIVED; |
1828 | 725 | } |
1829 | 1.13k | } |
1830 | | |
1831 | | METHOD(tls_handshake_t, get_peer_id, identification_t*, |
1832 | | private_tls_server_t *this) |
1833 | 0 | { |
1834 | 0 | return this->peer; |
1835 | 0 | } |
1836 | | |
1837 | | METHOD(tls_handshake_t, get_server_id, identification_t*, |
1838 | | private_tls_server_t *this) |
1839 | 0 | { |
1840 | 0 | return this->server; |
1841 | 0 | } |
1842 | | |
1843 | | METHOD(tls_handshake_t, get_auth, auth_cfg_t*, |
1844 | | private_tls_server_t *this) |
1845 | 0 | { |
1846 | 0 | return this->peer_auth; |
1847 | 0 | } |
1848 | | |
1849 | | METHOD(tls_handshake_t, destroy, void, |
1850 | | private_tls_server_t *this) |
1851 | 475 | { |
1852 | 475 | DESTROY_IF(this->private); |
1853 | 475 | DESTROY_IF(this->dh); |
1854 | 475 | DESTROY_IF(this->peer); |
1855 | 475 | this->server->destroy(this->server); |
1856 | 475 | this->peer_auth->destroy(this->peer_auth); |
1857 | 475 | this->server_auth->destroy(this->server_auth); |
1858 | 475 | free(this->hashsig.ptr); |
1859 | 475 | free(this->curves.ptr); |
1860 | 475 | free(this->session.ptr); |
1861 | 475 | free(this); |
1862 | 475 | } |
1863 | | |
1864 | | /** |
1865 | | * See header |
1866 | | */ |
1867 | | tls_server_t *tls_server_create(tls_t *tls, |
1868 | | tls_crypto_t *crypto, tls_alert_t *alert, |
1869 | | identification_t *server, identification_t *peer) |
1870 | 475 | { |
1871 | 475 | private_tls_server_t *this; |
1872 | | |
1873 | 475 | INIT(this, |
1874 | 475 | .public = { |
1875 | 475 | .handshake = { |
1876 | 475 | .process = _process, |
1877 | 475 | .build = _build, |
1878 | 475 | .cipherspec_changed = _cipherspec_changed, |
1879 | 475 | .change_cipherspec = _change_cipherspec, |
1880 | 475 | .finished = _finished, |
1881 | 475 | .get_peer_id = _get_peer_id, |
1882 | 475 | .get_server_id = _get_server_id, |
1883 | 475 | .get_auth = _get_auth, |
1884 | 475 | .destroy = _destroy, |
1885 | 475 | }, |
1886 | 475 | }, |
1887 | 475 | .tls = tls, |
1888 | 475 | .crypto = crypto, |
1889 | 475 | .alert = alert, |
1890 | 475 | .server = server->clone(server), |
1891 | 475 | .peer = peer ? peer->clone(peer) : NULL, |
1892 | 475 | .state = STATE_INIT, |
1893 | 475 | .peer_auth = auth_cfg_create(), |
1894 | 475 | .server_auth = auth_cfg_create(), |
1895 | 475 | .send_certreq_authorities = lib->settings->get_bool(lib->settings, |
1896 | 475 | "%s.tls.send_certreq_authorities", |
1897 | 475 | TRUE, lib->ns), |
1898 | 475 | ); |
1899 | | |
1900 | 475 | return &this->public; |
1901 | 475 | } |