Disconnect hostapd from building in base
[dragonfly.git] / contrib / hostapd / src / tls / tlsv1_client_read.c
CommitLineData
a875087d
JL
1/*
2 * TLSv1 client - read handshake message
4781064b 3 * Copyright (c) 2006-2011, Jouni Malinen <j@w1.fi>
a875087d 4 *
4781064b
JM
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
a875087d
JL
7 */
8
9#include "includes.h"
10
11#include "common.h"
4781064b
JM
12#include "crypto/md5.h"
13#include "crypto/sha1.h"
14#include "crypto/sha256.h"
15#include "crypto/tls.h"
a875087d 16#include "x509v3.h"
a875087d
JL
17#include "tlsv1_common.h"
18#include "tlsv1_record.h"
19#include "tlsv1_client.h"
20#include "tlsv1_client_i.h"
21
22static int tls_process_server_key_exchange(struct tlsv1_client *conn, u8 ct,
23 const u8 *in_data, size_t *in_len);
24static int tls_process_certificate_request(struct tlsv1_client *conn, u8 ct,
25 const u8 *in_data, size_t *in_len);
26static int tls_process_server_hello_done(struct tlsv1_client *conn, u8 ct,
27 const u8 *in_data, size_t *in_len);
28
29
30static int tls_process_server_hello(struct tlsv1_client *conn, u8 ct,
31 const u8 *in_data, size_t *in_len)
32{
33 const u8 *pos, *end;
34 size_t left, len, i;
35 u16 cipher_suite;
4781064b 36 u16 tls_version;
a875087d
JL
37
38 if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
39 wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
40 "received content type 0x%x", ct);
41 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
42 TLS_ALERT_UNEXPECTED_MESSAGE);
43 return -1;
44 }
45
46 pos = in_data;
47 left = *in_len;
48
49 if (left < 4)
50 goto decode_error;
51
52 /* HandshakeType msg_type */
53 if (*pos != TLS_HANDSHAKE_TYPE_SERVER_HELLO) {
54 wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
55 "message %d (expected ServerHello)", *pos);
56 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
57 TLS_ALERT_UNEXPECTED_MESSAGE);
58 return -1;
59 }
60 wpa_printf(MSG_DEBUG, "TLSv1: Received ServerHello");
61 pos++;
62 /* uint24 length */
63 len = WPA_GET_BE24(pos);
64 pos += 3;
65 left -= 4;
66
67 if (len > left)
68 goto decode_error;
69
70 /* body - ServerHello */
71
72 wpa_hexdump(MSG_MSGDUMP, "TLSv1: ServerHello", pos, len);
73 end = pos + len;
74
75 /* ProtocolVersion server_version */
76 if (end - pos < 2)
77 goto decode_error;
4781064b
JM
78 tls_version = WPA_GET_BE16(pos);
79 if (!tls_version_ok(tls_version)) {
a875087d 80 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected protocol version in "
4781064b 81 "ServerHello %u.%u", pos[0], pos[1]);
a875087d
JL
82 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
83 TLS_ALERT_PROTOCOL_VERSION);
84 return -1;
85 }
86 pos += 2;
87
4781064b
JM
88 wpa_printf(MSG_DEBUG, "TLSv1: Using TLS v%s",
89 tls_version_str(tls_version));
90 conn->rl.tls_version = tls_version;
91
a875087d
JL
92 /* Random random */
93 if (end - pos < TLS_RANDOM_LEN)
94 goto decode_error;
95
96 os_memcpy(conn->server_random, pos, TLS_RANDOM_LEN);
97 pos += TLS_RANDOM_LEN;
98 wpa_hexdump(MSG_MSGDUMP, "TLSv1: server_random",
99 conn->server_random, TLS_RANDOM_LEN);
100
101 /* SessionID session_id */
102 if (end - pos < 1)
103 goto decode_error;
104 if (end - pos < 1 + *pos || *pos > TLS_SESSION_ID_MAX_LEN)
105 goto decode_error;
106 if (conn->session_id_len && conn->session_id_len == *pos &&
107 os_memcmp(conn->session_id, pos + 1, conn->session_id_len) == 0) {
108 pos += 1 + conn->session_id_len;
109 wpa_printf(MSG_DEBUG, "TLSv1: Resuming old session");
110 conn->session_resumed = 1;
111 } else {
112 conn->session_id_len = *pos;
113 pos++;
114 os_memcpy(conn->session_id, pos, conn->session_id_len);
115 pos += conn->session_id_len;
116 }
117 wpa_hexdump(MSG_MSGDUMP, "TLSv1: session_id",
118 conn->session_id, conn->session_id_len);
119
120 /* CipherSuite cipher_suite */
121 if (end - pos < 2)
122 goto decode_error;
123 cipher_suite = WPA_GET_BE16(pos);
124 pos += 2;
125 for (i = 0; i < conn->num_cipher_suites; i++) {
126 if (cipher_suite == conn->cipher_suites[i])
127 break;
128 }
129 if (i == conn->num_cipher_suites) {
130 wpa_printf(MSG_INFO, "TLSv1: Server selected unexpected "
131 "cipher suite 0x%04x", cipher_suite);
132 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
133 TLS_ALERT_ILLEGAL_PARAMETER);
134 return -1;
135 }
136
137 if (conn->session_resumed && cipher_suite != conn->prev_cipher_suite) {
138 wpa_printf(MSG_DEBUG, "TLSv1: Server selected a different "
139 "cipher suite for a resumed connection (0x%04x != "
140 "0x%04x)", cipher_suite, conn->prev_cipher_suite);
141 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
142 TLS_ALERT_ILLEGAL_PARAMETER);
143 return -1;
144 }
145
146 if (tlsv1_record_set_cipher_suite(&conn->rl, cipher_suite) < 0) {
147 wpa_printf(MSG_DEBUG, "TLSv1: Failed to set CipherSuite for "
148 "record layer");
149 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
150 TLS_ALERT_INTERNAL_ERROR);
151 return -1;
152 }
153
154 conn->prev_cipher_suite = cipher_suite;
155
156 /* CompressionMethod compression_method */
157 if (end - pos < 1)
158 goto decode_error;
159 if (*pos != TLS_COMPRESSION_NULL) {
160 wpa_printf(MSG_INFO, "TLSv1: Server selected unexpected "
161 "compression 0x%02x", *pos);
162 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
163 TLS_ALERT_ILLEGAL_PARAMETER);
164 return -1;
165 }
166 pos++;
167
168 if (end != pos) {
169 /* TODO: ServerHello extensions */
170 wpa_hexdump(MSG_DEBUG, "TLSv1: Unexpected extra data in the "
171 "end of ServerHello", pos, end - pos);
172 goto decode_error;
173 }
174
175 if (conn->session_ticket_included && conn->session_ticket_cb) {
176 /* TODO: include SessionTicket extension if one was included in
177 * ServerHello */
178 int res = conn->session_ticket_cb(
179 conn->session_ticket_cb_ctx, NULL, 0,
180 conn->client_random, conn->server_random,
181 conn->master_secret);
182 if (res < 0) {
183 wpa_printf(MSG_DEBUG, "TLSv1: SessionTicket callback "
184 "indicated failure");
185 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
186 TLS_ALERT_HANDSHAKE_FAILURE);
187 return -1;
188 }
189 conn->use_session_ticket = !!res;
190 }
191
192 if ((conn->session_resumed || conn->use_session_ticket) &&
193 tls_derive_keys(conn, NULL, 0)) {
194 wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive keys");
195 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
196 TLS_ALERT_INTERNAL_ERROR);
197 return -1;
198 }
199
200 *in_len = end - in_data;
201
202 conn->state = (conn->session_resumed || conn->use_session_ticket) ?
203 SERVER_CHANGE_CIPHER_SPEC : SERVER_CERTIFICATE;
204
205 return 0;
206
207decode_error:
208 wpa_printf(MSG_DEBUG, "TLSv1: Failed to decode ServerHello");
209 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
210 return -1;
211}
212
213
214static int tls_process_certificate(struct tlsv1_client *conn, u8 ct,
215 const u8 *in_data, size_t *in_len)
216{
217 const u8 *pos, *end;
218 size_t left, len, list_len, cert_len, idx;
219 u8 type;
220 struct x509_certificate *chain = NULL, *last = NULL, *cert;
221 int reason;
222
223 if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
224 wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
225 "received content type 0x%x", ct);
226 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
227 TLS_ALERT_UNEXPECTED_MESSAGE);
228 return -1;
229 }
230
231 pos = in_data;
232 left = *in_len;
233
234 if (left < 4) {
235 wpa_printf(MSG_DEBUG, "TLSv1: Too short Certificate message "
236 "(len=%lu)", (unsigned long) left);
237 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
238 return -1;
239 }
240
241 type = *pos++;
242 len = WPA_GET_BE24(pos);
243 pos += 3;
244 left -= 4;
245
246 if (len > left) {
247 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected Certificate message "
248 "length (len=%lu != left=%lu)",
249 (unsigned long) len, (unsigned long) left);
250 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
251 return -1;
252 }
253
254 if (type == TLS_HANDSHAKE_TYPE_SERVER_KEY_EXCHANGE)
255 return tls_process_server_key_exchange(conn, ct, in_data,
256 in_len);
257 if (type == TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST)
258 return tls_process_certificate_request(conn, ct, in_data,
259 in_len);
260 if (type == TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE)
261 return tls_process_server_hello_done(conn, ct, in_data,
262 in_len);
263 if (type != TLS_HANDSHAKE_TYPE_CERTIFICATE) {
264 wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
265 "message %d (expected Certificate/"
266 "ServerKeyExchange/CertificateRequest/"
267 "ServerHelloDone)", type);
268 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
269 TLS_ALERT_UNEXPECTED_MESSAGE);
270 return -1;
271 }
272
273 wpa_printf(MSG_DEBUG,
274 "TLSv1: Received Certificate (certificate_list len %lu)",
275 (unsigned long) len);
276
277 /*
278 * opaque ASN.1Cert<2^24-1>;
279 *
280 * struct {
281 * ASN.1Cert certificate_list<1..2^24-1>;
282 * } Certificate;
283 */
284
285 end = pos + len;
286
287 if (end - pos < 3) {
288 wpa_printf(MSG_DEBUG, "TLSv1: Too short Certificate "
289 "(left=%lu)", (unsigned long) left);
290 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
291 return -1;
292 }
293
294 list_len = WPA_GET_BE24(pos);
295 pos += 3;
296
297 if ((size_t) (end - pos) != list_len) {
298 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected certificate_list "
299 "length (len=%lu left=%lu)",
300 (unsigned long) list_len,
301 (unsigned long) (end - pos));
302 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
303 return -1;
304 }
305
306 idx = 0;
307 while (pos < end) {
308 if (end - pos < 3) {
309 wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse "
310 "certificate_list");
311 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
312 TLS_ALERT_DECODE_ERROR);
313 x509_certificate_chain_free(chain);
314 return -1;
315 }
316
317 cert_len = WPA_GET_BE24(pos);
318 pos += 3;
319
320 if ((size_t) (end - pos) < cert_len) {
321 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected certificate "
322 "length (len=%lu left=%lu)",
323 (unsigned long) cert_len,
324 (unsigned long) (end - pos));
325 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
326 TLS_ALERT_DECODE_ERROR);
327 x509_certificate_chain_free(chain);
328 return -1;
329 }
330
331 wpa_printf(MSG_DEBUG, "TLSv1: Certificate %lu (len %lu)",
332 (unsigned long) idx, (unsigned long) cert_len);
333
334 if (idx == 0) {
335 crypto_public_key_free(conn->server_rsa_key);
336 if (tls_parse_cert(pos, cert_len,
337 &conn->server_rsa_key)) {
338 wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse "
339 "the certificate");
340 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
341 TLS_ALERT_BAD_CERTIFICATE);
342 x509_certificate_chain_free(chain);
343 return -1;
344 }
345 }
346
347 cert = x509_certificate_parse(pos, cert_len);
348 if (cert == NULL) {
349 wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse "
350 "the certificate");
351 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
352 TLS_ALERT_BAD_CERTIFICATE);
353 x509_certificate_chain_free(chain);
354 return -1;
355 }
356
357 if (last == NULL)
358 chain = cert;
359 else
360 last->next = cert;
361 last = cert;
362
363 idx++;
364 pos += cert_len;
365 }
366
367 if (conn->cred &&
368 x509_certificate_chain_validate(conn->cred->trusted_certs, chain,
4781064b
JM
369 &reason, conn->disable_time_checks)
370 < 0) {
a875087d
JL
371 int tls_reason;
372 wpa_printf(MSG_DEBUG, "TLSv1: Server certificate chain "
373 "validation failed (reason=%d)", reason);
374 switch (reason) {
375 case X509_VALIDATE_BAD_CERTIFICATE:
376 tls_reason = TLS_ALERT_BAD_CERTIFICATE;
377 break;
378 case X509_VALIDATE_UNSUPPORTED_CERTIFICATE:
379 tls_reason = TLS_ALERT_UNSUPPORTED_CERTIFICATE;
380 break;
381 case X509_VALIDATE_CERTIFICATE_REVOKED:
382 tls_reason = TLS_ALERT_CERTIFICATE_REVOKED;
383 break;
384 case X509_VALIDATE_CERTIFICATE_EXPIRED:
385 tls_reason = TLS_ALERT_CERTIFICATE_EXPIRED;
386 break;
387 case X509_VALIDATE_CERTIFICATE_UNKNOWN:
388 tls_reason = TLS_ALERT_CERTIFICATE_UNKNOWN;
389 break;
390 case X509_VALIDATE_UNKNOWN_CA:
391 tls_reason = TLS_ALERT_UNKNOWN_CA;
392 break;
393 default:
394 tls_reason = TLS_ALERT_BAD_CERTIFICATE;
395 break;
396 }
397 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, tls_reason);
398 x509_certificate_chain_free(chain);
399 return -1;
400 }
401
402 x509_certificate_chain_free(chain);
403
404 *in_len = end - in_data;
405
406 conn->state = SERVER_KEY_EXCHANGE;
407
408 return 0;
409}
410
411
412static int tlsv1_process_diffie_hellman(struct tlsv1_client *conn,
413 const u8 *buf, size_t len)
414{
415 const u8 *pos, *end;
416
417 tlsv1_client_free_dh(conn);
418
419 pos = buf;
420 end = buf + len;
421
422 if (end - pos < 3)
423 goto fail;
424 conn->dh_p_len = WPA_GET_BE16(pos);
425 pos += 2;
426 if (conn->dh_p_len == 0 || end - pos < (int) conn->dh_p_len) {
427 wpa_printf(MSG_DEBUG, "TLSv1: Invalid dh_p length %lu",
428 (unsigned long) conn->dh_p_len);
429 goto fail;
430 }
431 conn->dh_p = os_malloc(conn->dh_p_len);
432 if (conn->dh_p == NULL)
433 goto fail;
434 os_memcpy(conn->dh_p, pos, conn->dh_p_len);
435 pos += conn->dh_p_len;
436 wpa_hexdump(MSG_DEBUG, "TLSv1: DH p (prime)",
437 conn->dh_p, conn->dh_p_len);
438
439 if (end - pos < 3)
440 goto fail;
441 conn->dh_g_len = WPA_GET_BE16(pos);
442 pos += 2;
443 if (conn->dh_g_len == 0 || end - pos < (int) conn->dh_g_len)
444 goto fail;
445 conn->dh_g = os_malloc(conn->dh_g_len);
446 if (conn->dh_g == NULL)
447 goto fail;
448 os_memcpy(conn->dh_g, pos, conn->dh_g_len);
449 pos += conn->dh_g_len;
450 wpa_hexdump(MSG_DEBUG, "TLSv1: DH g (generator)",
451 conn->dh_g, conn->dh_g_len);
452 if (conn->dh_g_len == 1 && conn->dh_g[0] < 2)
453 goto fail;
454
455 if (end - pos < 3)
456 goto fail;
457 conn->dh_ys_len = WPA_GET_BE16(pos);
458 pos += 2;
459 if (conn->dh_ys_len == 0 || end - pos < (int) conn->dh_ys_len)
460 goto fail;
461 conn->dh_ys = os_malloc(conn->dh_ys_len);
462 if (conn->dh_ys == NULL)
463 goto fail;
464 os_memcpy(conn->dh_ys, pos, conn->dh_ys_len);
465 pos += conn->dh_ys_len;
466 wpa_hexdump(MSG_DEBUG, "TLSv1: DH Ys (server's public value)",
467 conn->dh_ys, conn->dh_ys_len);
468
469 return 0;
470
471fail:
472 wpa_printf(MSG_DEBUG, "TLSv1: Processing DH params failed");
473 tlsv1_client_free_dh(conn);
474 return -1;
475}
476
477
478static int tls_process_server_key_exchange(struct tlsv1_client *conn, u8 ct,
479 const u8 *in_data, size_t *in_len)
480{
481 const u8 *pos, *end;
482 size_t left, len;
483 u8 type;
484 const struct tls_cipher_suite *suite;
485
486 if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
487 wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
488 "received content type 0x%x", ct);
489 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
490 TLS_ALERT_UNEXPECTED_MESSAGE);
491 return -1;
492 }
493
494 pos = in_data;
495 left = *in_len;
496
497 if (left < 4) {
498 wpa_printf(MSG_DEBUG, "TLSv1: Too short ServerKeyExchange "
499 "(Left=%lu)", (unsigned long) left);
500 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
501 return -1;
502 }
503
504 type = *pos++;
505 len = WPA_GET_BE24(pos);
506 pos += 3;
507 left -= 4;
508
509 if (len > left) {
510 wpa_printf(MSG_DEBUG, "TLSv1: Mismatch in ServerKeyExchange "
511 "length (len=%lu != left=%lu)",
512 (unsigned long) len, (unsigned long) left);
513 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
514 return -1;
515 }
516
517 end = pos + len;
518
519 if (type == TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST)
520 return tls_process_certificate_request(conn, ct, in_data,
521 in_len);
522 if (type == TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE)
523 return tls_process_server_hello_done(conn, ct, in_data,
524 in_len);
525 if (type != TLS_HANDSHAKE_TYPE_SERVER_KEY_EXCHANGE) {
526 wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
527 "message %d (expected ServerKeyExchange/"
528 "CertificateRequest/ServerHelloDone)", type);
529 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
530 TLS_ALERT_UNEXPECTED_MESSAGE);
531 return -1;
532 }
533
534 wpa_printf(MSG_DEBUG, "TLSv1: Received ServerKeyExchange");
535
536 if (!tls_server_key_exchange_allowed(conn->rl.cipher_suite)) {
537 wpa_printf(MSG_DEBUG, "TLSv1: ServerKeyExchange not allowed "
538 "with the selected cipher suite");
539 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
540 TLS_ALERT_UNEXPECTED_MESSAGE);
541 return -1;
542 }
543
544 wpa_hexdump(MSG_DEBUG, "TLSv1: ServerKeyExchange", pos, len);
545 suite = tls_get_cipher_suite(conn->rl.cipher_suite);
546 if (suite && suite->key_exchange == TLS_KEY_X_DH_anon) {
547 if (tlsv1_process_diffie_hellman(conn, pos, len) < 0) {
548 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
549 TLS_ALERT_DECODE_ERROR);
550 return -1;
551 }
552 } else {
553 wpa_printf(MSG_DEBUG, "TLSv1: UnexpectedServerKeyExchange");
554 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
555 TLS_ALERT_UNEXPECTED_MESSAGE);
556 return -1;
557 }
558
559 *in_len = end - in_data;
560
561 conn->state = SERVER_CERTIFICATE_REQUEST;
562
563 return 0;
564}
565
566
567static int tls_process_certificate_request(struct tlsv1_client *conn, u8 ct,
568 const u8 *in_data, size_t *in_len)
569{
570 const u8 *pos, *end;
571 size_t left, len;
572 u8 type;
573
574 if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
575 wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
576 "received content type 0x%x", ct);
577 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
578 TLS_ALERT_UNEXPECTED_MESSAGE);
579 return -1;
580 }
581
582 pos = in_data;
583 left = *in_len;
584
585 if (left < 4) {
586 wpa_printf(MSG_DEBUG, "TLSv1: Too short CertificateRequest "
587 "(left=%lu)", (unsigned long) left);
588 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
589 return -1;
590 }
591
592 type = *pos++;
593 len = WPA_GET_BE24(pos);
594 pos += 3;
595 left -= 4;
596
597 if (len > left) {
598 wpa_printf(MSG_DEBUG, "TLSv1: Mismatch in CertificateRequest "
599 "length (len=%lu != left=%lu)",
600 (unsigned long) len, (unsigned long) left);
601 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
602 return -1;
603 }
604
605 end = pos + len;
606
607 if (type == TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE)
608 return tls_process_server_hello_done(conn, ct, in_data,
609 in_len);
610 if (type != TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST) {
611 wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
612 "message %d (expected CertificateRequest/"
613 "ServerHelloDone)", type);
614 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
615 TLS_ALERT_UNEXPECTED_MESSAGE);
616 return -1;
617 }
618
619 wpa_printf(MSG_DEBUG, "TLSv1: Received CertificateRequest");
620
621 conn->certificate_requested = 1;
622
623 *in_len = end - in_data;
624
625 conn->state = SERVER_HELLO_DONE;
626
627 return 0;
628}
629
630
631static int tls_process_server_hello_done(struct tlsv1_client *conn, u8 ct,
632 const u8 *in_data, size_t *in_len)
633{
634 const u8 *pos, *end;
635 size_t left, len;
636 u8 type;
637
638 if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
639 wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
640 "received content type 0x%x", ct);
641 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
642 TLS_ALERT_UNEXPECTED_MESSAGE);
643 return -1;
644 }
645
646 pos = in_data;
647 left = *in_len;
648
649 if (left < 4) {
650 wpa_printf(MSG_DEBUG, "TLSv1: Too short ServerHelloDone "
651 "(left=%lu)", (unsigned long) left);
652 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
653 return -1;
654 }
655
656 type = *pos++;
657 len = WPA_GET_BE24(pos);
658 pos += 3;
659 left -= 4;
660
661 if (len > left) {
662 wpa_printf(MSG_DEBUG, "TLSv1: Mismatch in ServerHelloDone "
663 "length (len=%lu != left=%lu)",
664 (unsigned long) len, (unsigned long) left);
665 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
666 return -1;
667 }
668 end = pos + len;
669
670 if (type != TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE) {
671 wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
672 "message %d (expected ServerHelloDone)", type);
673 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
674 TLS_ALERT_UNEXPECTED_MESSAGE);
675 return -1;
676 }
677
678 wpa_printf(MSG_DEBUG, "TLSv1: Received ServerHelloDone");
679
680 *in_len = end - in_data;
681
682 conn->state = CLIENT_KEY_EXCHANGE;
683
684 return 0;
685}
686
687
688static int tls_process_server_change_cipher_spec(struct tlsv1_client *conn,
689 u8 ct, const u8 *in_data,
690 size_t *in_len)
691{
692 const u8 *pos;
693 size_t left;
694
695 if (ct != TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC) {
696 wpa_printf(MSG_DEBUG, "TLSv1: Expected ChangeCipherSpec; "
697 "received content type 0x%x", ct);
698 if (conn->use_session_ticket) {
699 int res;
700 wpa_printf(MSG_DEBUG, "TLSv1: Server may have "
701 "rejected SessionTicket");
702 conn->use_session_ticket = 0;
703
704 /* Notify upper layers that SessionTicket failed */
705 res = conn->session_ticket_cb(
706 conn->session_ticket_cb_ctx, NULL, 0, NULL,
707 NULL, NULL);
708 if (res < 0) {
709 wpa_printf(MSG_DEBUG, "TLSv1: SessionTicket "
710 "callback indicated failure");
711 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
712 TLS_ALERT_HANDSHAKE_FAILURE);
713 return -1;
714 }
715
716 conn->state = SERVER_CERTIFICATE;
717 return tls_process_certificate(conn, ct, in_data,
718 in_len);
719 }
720 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
721 TLS_ALERT_UNEXPECTED_MESSAGE);
722 return -1;
723 }
724
725 pos = in_data;
726 left = *in_len;
727
728 if (left < 1) {
729 wpa_printf(MSG_DEBUG, "TLSv1: Too short ChangeCipherSpec");
730 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
731 return -1;
732 }
733
734 if (*pos != TLS_CHANGE_CIPHER_SPEC) {
735 wpa_printf(MSG_DEBUG, "TLSv1: Expected ChangeCipherSpec; "
736 "received data 0x%x", *pos);
737 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
738 TLS_ALERT_UNEXPECTED_MESSAGE);
739 return -1;
740 }
741
742 wpa_printf(MSG_DEBUG, "TLSv1: Received ChangeCipherSpec");
743 if (tlsv1_record_change_read_cipher(&conn->rl) < 0) {
744 wpa_printf(MSG_DEBUG, "TLSv1: Failed to change read cipher "
745 "for record layer");
746 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
747 TLS_ALERT_INTERNAL_ERROR);
748 return -1;
749 }
750
751 *in_len = pos + 1 - in_data;
752
753 conn->state = SERVER_FINISHED;
754
755 return 0;
756}
757
758
759static int tls_process_server_finished(struct tlsv1_client *conn, u8 ct,
760 const u8 *in_data, size_t *in_len)
761{
762 const u8 *pos, *end;
763 size_t left, len, hlen;
764 u8 verify_data[TLS_VERIFY_DATA_LEN];
765 u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN];
766
767 if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
768 wpa_printf(MSG_DEBUG, "TLSv1: Expected Finished; "
769 "received content type 0x%x", ct);
770 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
771 TLS_ALERT_UNEXPECTED_MESSAGE);
772 return -1;
773 }
774
775 pos = in_data;
776 left = *in_len;
777
778 if (left < 4) {
779 wpa_printf(MSG_DEBUG, "TLSv1: Too short record (left=%lu) for "
780 "Finished",
781 (unsigned long) left);
782 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
783 TLS_ALERT_DECODE_ERROR);
784 return -1;
785 }
786
787 if (pos[0] != TLS_HANDSHAKE_TYPE_FINISHED) {
788 wpa_printf(MSG_DEBUG, "TLSv1: Expected Finished; received "
789 "type 0x%x", pos[0]);
790 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
791 TLS_ALERT_UNEXPECTED_MESSAGE);
792 return -1;
793 }
794
795 len = WPA_GET_BE24(pos + 1);
796
797 pos += 4;
798 left -= 4;
799
800 if (len > left) {
801 wpa_printf(MSG_DEBUG, "TLSv1: Too short buffer for Finished "
802 "(len=%lu > left=%lu)",
803 (unsigned long) len, (unsigned long) left);
804 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
805 TLS_ALERT_DECODE_ERROR);
806 return -1;
807 }
808 end = pos + len;
809 if (len != TLS_VERIFY_DATA_LEN) {
810 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected verify_data length "
811 "in Finished: %lu (expected %d)",
812 (unsigned long) len, TLS_VERIFY_DATA_LEN);
813 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
814 TLS_ALERT_DECODE_ERROR);
815 return -1;
816 }
817 wpa_hexdump(MSG_MSGDUMP, "TLSv1: verify_data in Finished",
818 pos, TLS_VERIFY_DATA_LEN);
819
4781064b
JM
820#ifdef CONFIG_TLSV12
821 if (conn->rl.tls_version >= TLS_VERSION_1_2) {
822 hlen = SHA256_MAC_LEN;
823 if (conn->verify.sha256_server == NULL ||
824 crypto_hash_finish(conn->verify.sha256_server, hash, &hlen)
825 < 0) {
826 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
827 TLS_ALERT_INTERNAL_ERROR);
828 conn->verify.sha256_server = NULL;
829 return -1;
830 }
831 conn->verify.sha256_server = NULL;
832 } else {
833#endif /* CONFIG_TLSV12 */
834
a875087d
JL
835 hlen = MD5_MAC_LEN;
836 if (conn->verify.md5_server == NULL ||
837 crypto_hash_finish(conn->verify.md5_server, hash, &hlen) < 0) {
838 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
839 TLS_ALERT_INTERNAL_ERROR);
840 conn->verify.md5_server = NULL;
841 crypto_hash_finish(conn->verify.sha1_server, NULL, NULL);
842 conn->verify.sha1_server = NULL;
843 return -1;
844 }
845 conn->verify.md5_server = NULL;
846 hlen = SHA1_MAC_LEN;
847 if (conn->verify.sha1_server == NULL ||
848 crypto_hash_finish(conn->verify.sha1_server, hash + MD5_MAC_LEN,
849 &hlen) < 0) {
850 conn->verify.sha1_server = NULL;
851 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
852 TLS_ALERT_INTERNAL_ERROR);
853 return -1;
854 }
855 conn->verify.sha1_server = NULL;
4781064b
JM
856 hlen = MD5_MAC_LEN + SHA1_MAC_LEN;
857
858#ifdef CONFIG_TLSV12
859 }
860#endif /* CONFIG_TLSV12 */
a875087d 861
4781064b
JM
862 if (tls_prf(conn->rl.tls_version,
863 conn->master_secret, TLS_MASTER_SECRET_LEN,
864 "server finished", hash, hlen,
a875087d
JL
865 verify_data, TLS_VERIFY_DATA_LEN)) {
866 wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive verify_data");
867 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
868 TLS_ALERT_DECRYPT_ERROR);
869 return -1;
870 }
871 wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (server)",
872 verify_data, TLS_VERIFY_DATA_LEN);
873
874 if (os_memcmp(pos, verify_data, TLS_VERIFY_DATA_LEN) != 0) {
875 wpa_printf(MSG_INFO, "TLSv1: Mismatch in verify_data");
876 return -1;
877 }
878
879 wpa_printf(MSG_DEBUG, "TLSv1: Received Finished");
880
881 *in_len = end - in_data;
882
883 conn->state = (conn->session_resumed || conn->use_session_ticket) ?
884 CHANGE_CIPHER_SPEC : ACK_FINISHED;
885
886 return 0;
887}
888
889
890static int tls_process_application_data(struct tlsv1_client *conn, u8 ct,
891 const u8 *in_data, size_t *in_len,
892 u8 **out_data, size_t *out_len)
893{
894 const u8 *pos;
895 size_t left;
896
897 if (ct != TLS_CONTENT_TYPE_APPLICATION_DATA) {
898 wpa_printf(MSG_DEBUG, "TLSv1: Expected Application Data; "
899 "received content type 0x%x", ct);
900 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
901 TLS_ALERT_UNEXPECTED_MESSAGE);
902 return -1;
903 }
904
905 pos = in_data;
906 left = *in_len;
907
908 wpa_hexdump(MSG_DEBUG, "TLSv1: Application Data included in Handshake",
909 pos, left);
910
911 *out_data = os_malloc(left);
912 if (*out_data) {
913 os_memcpy(*out_data, pos, left);
914 *out_len = left;
915 }
916
917 return 0;
918}
919
920
921int tlsv1_client_process_handshake(struct tlsv1_client *conn, u8 ct,
922 const u8 *buf, size_t *len,
923 u8 **out_data, size_t *out_len)
924{
925 if (ct == TLS_CONTENT_TYPE_ALERT) {
926 if (*len < 2) {
927 wpa_printf(MSG_DEBUG, "TLSv1: Alert underflow");
928 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
929 TLS_ALERT_DECODE_ERROR);
930 return -1;
931 }
932 wpa_printf(MSG_DEBUG, "TLSv1: Received alert %d:%d",
933 buf[0], buf[1]);
934 *len = 2;
935 conn->state = FAILED;
936 return -1;
937 }
938
939 if (ct == TLS_CONTENT_TYPE_HANDSHAKE && *len >= 4 &&
940 buf[0] == TLS_HANDSHAKE_TYPE_HELLO_REQUEST) {
941 size_t hr_len = WPA_GET_BE24(buf + 1);
942 if (hr_len > *len - 4) {
943 wpa_printf(MSG_DEBUG, "TLSv1: HelloRequest underflow");
944 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
945 TLS_ALERT_DECODE_ERROR);
946 return -1;
947 }
948 wpa_printf(MSG_DEBUG, "TLSv1: Ignored HelloRequest");
949 *len = 4 + hr_len;
950 return 0;
951 }
952
953 switch (conn->state) {
954 case SERVER_HELLO:
955 if (tls_process_server_hello(conn, ct, buf, len))
956 return -1;
957 break;
958 case SERVER_CERTIFICATE:
959 if (tls_process_certificate(conn, ct, buf, len))
960 return -1;
961 break;
962 case SERVER_KEY_EXCHANGE:
963 if (tls_process_server_key_exchange(conn, ct, buf, len))
964 return -1;
965 break;
966 case SERVER_CERTIFICATE_REQUEST:
967 if (tls_process_certificate_request(conn, ct, buf, len))
968 return -1;
969 break;
970 case SERVER_HELLO_DONE:
971 if (tls_process_server_hello_done(conn, ct, buf, len))
972 return -1;
973 break;
974 case SERVER_CHANGE_CIPHER_SPEC:
975 if (tls_process_server_change_cipher_spec(conn, ct, buf, len))
976 return -1;
977 break;
978 case SERVER_FINISHED:
979 if (tls_process_server_finished(conn, ct, buf, len))
980 return -1;
981 break;
982 case ACK_FINISHED:
983 if (out_data &&
984 tls_process_application_data(conn, ct, buf, len, out_data,
985 out_len))
986 return -1;
987 break;
988 default:
989 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected state %d "
990 "while processing received message",
991 conn->state);
992 return -1;
993 }
994
995 if (ct == TLS_CONTENT_TYPE_HANDSHAKE)
996 tls_verify_hash_add(&conn->verify, buf, *len);
997
998 return 0;
999}