2 * TLSv1 client - read handshake message
3 * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
9 * Alternatively, this software may be distributed under the terms of BSD
12 * See README and COPYING for more details.
18 #include "crypto/md5.h"
19 #include "crypto/sha1.h"
20 #include "crypto/tls.h"
22 #include "tlsv1_common.h"
23 #include "tlsv1_record.h"
24 #include "tlsv1_client.h"
25 #include "tlsv1_client_i.h"
27 static int tls_process_server_key_exchange(struct tlsv1_client
*conn
, u8 ct
,
28 const u8
*in_data
, size_t *in_len
);
29 static int tls_process_certificate_request(struct tlsv1_client
*conn
, u8 ct
,
30 const u8
*in_data
, size_t *in_len
);
31 static int tls_process_server_hello_done(struct tlsv1_client
*conn
, u8 ct
,
32 const u8
*in_data
, size_t *in_len
);
35 static int tls_process_server_hello(struct tlsv1_client
*conn
, u8 ct
,
36 const u8
*in_data
, size_t *in_len
)
42 if (ct
!= TLS_CONTENT_TYPE_HANDSHAKE
) {
43 wpa_printf(MSG_DEBUG
, "TLSv1: Expected Handshake; "
44 "received content type 0x%x", ct
);
45 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
46 TLS_ALERT_UNEXPECTED_MESSAGE
);
56 /* HandshakeType msg_type */
57 if (*pos
!= TLS_HANDSHAKE_TYPE_SERVER_HELLO
) {
58 wpa_printf(MSG_DEBUG
, "TLSv1: Received unexpected handshake "
59 "message %d (expected ServerHello)", *pos
);
60 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
61 TLS_ALERT_UNEXPECTED_MESSAGE
);
64 wpa_printf(MSG_DEBUG
, "TLSv1: Received ServerHello");
67 len
= WPA_GET_BE24(pos
);
74 /* body - ServerHello */
76 wpa_hexdump(MSG_MSGDUMP
, "TLSv1: ServerHello", pos
, len
);
79 /* ProtocolVersion server_version */
82 if (WPA_GET_BE16(pos
) != TLS_VERSION
) {
83 wpa_printf(MSG_DEBUG
, "TLSv1: Unexpected protocol version in "
85 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
86 TLS_ALERT_PROTOCOL_VERSION
);
92 if (end
- pos
< TLS_RANDOM_LEN
)
95 os_memcpy(conn
->server_random
, pos
, TLS_RANDOM_LEN
);
96 pos
+= TLS_RANDOM_LEN
;
97 wpa_hexdump(MSG_MSGDUMP
, "TLSv1: server_random",
98 conn
->server_random
, TLS_RANDOM_LEN
);
100 /* SessionID session_id */
103 if (end
- pos
< 1 + *pos
|| *pos
> TLS_SESSION_ID_MAX_LEN
)
105 if (conn
->session_id_len
&& conn
->session_id_len
== *pos
&&
106 os_memcmp(conn
->session_id
, pos
+ 1, conn
->session_id_len
) == 0) {
107 pos
+= 1 + conn
->session_id_len
;
108 wpa_printf(MSG_DEBUG
, "TLSv1: Resuming old session");
109 conn
->session_resumed
= 1;
111 conn
->session_id_len
= *pos
;
113 os_memcpy(conn
->session_id
, pos
, conn
->session_id_len
);
114 pos
+= conn
->session_id_len
;
116 wpa_hexdump(MSG_MSGDUMP
, "TLSv1: session_id",
117 conn
->session_id
, conn
->session_id_len
);
119 /* CipherSuite cipher_suite */
122 cipher_suite
= WPA_GET_BE16(pos
);
124 for (i
= 0; i
< conn
->num_cipher_suites
; i
++) {
125 if (cipher_suite
== conn
->cipher_suites
[i
])
128 if (i
== conn
->num_cipher_suites
) {
129 wpa_printf(MSG_INFO
, "TLSv1: Server selected unexpected "
130 "cipher suite 0x%04x", cipher_suite
);
131 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
132 TLS_ALERT_ILLEGAL_PARAMETER
);
136 if (conn
->session_resumed
&& cipher_suite
!= conn
->prev_cipher_suite
) {
137 wpa_printf(MSG_DEBUG
, "TLSv1: Server selected a different "
138 "cipher suite for a resumed connection (0x%04x != "
139 "0x%04x)", cipher_suite
, conn
->prev_cipher_suite
);
140 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
141 TLS_ALERT_ILLEGAL_PARAMETER
);
145 if (tlsv1_record_set_cipher_suite(&conn
->rl
, cipher_suite
) < 0) {
146 wpa_printf(MSG_DEBUG
, "TLSv1: Failed to set CipherSuite for "
148 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
149 TLS_ALERT_INTERNAL_ERROR
);
153 conn
->prev_cipher_suite
= cipher_suite
;
155 /* CompressionMethod compression_method */
158 if (*pos
!= TLS_COMPRESSION_NULL
) {
159 wpa_printf(MSG_INFO
, "TLSv1: Server selected unexpected "
160 "compression 0x%02x", *pos
);
161 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
162 TLS_ALERT_ILLEGAL_PARAMETER
);
168 /* TODO: ServerHello extensions */
169 wpa_hexdump(MSG_DEBUG
, "TLSv1: Unexpected extra data in the "
170 "end of ServerHello", pos
, end
- pos
);
174 if (conn
->session_ticket_included
&& conn
->session_ticket_cb
) {
175 /* TODO: include SessionTicket extension if one was included in
177 int res
= conn
->session_ticket_cb(
178 conn
->session_ticket_cb_ctx
, NULL
, 0,
179 conn
->client_random
, conn
->server_random
,
180 conn
->master_secret
);
182 wpa_printf(MSG_DEBUG
, "TLSv1: SessionTicket callback "
183 "indicated failure");
184 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
185 TLS_ALERT_HANDSHAKE_FAILURE
);
188 conn
->use_session_ticket
= !!res
;
191 if ((conn
->session_resumed
|| conn
->use_session_ticket
) &&
192 tls_derive_keys(conn
, NULL
, 0)) {
193 wpa_printf(MSG_DEBUG
, "TLSv1: Failed to derive keys");
194 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
195 TLS_ALERT_INTERNAL_ERROR
);
199 *in_len
= end
- in_data
;
201 conn
->state
= (conn
->session_resumed
|| conn
->use_session_ticket
) ?
202 SERVER_CHANGE_CIPHER_SPEC
: SERVER_CERTIFICATE
;
207 wpa_printf(MSG_DEBUG
, "TLSv1: Failed to decode ServerHello");
208 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
, TLS_ALERT_DECODE_ERROR
);
213 static int tls_process_certificate(struct tlsv1_client
*conn
, u8 ct
,
214 const u8
*in_data
, size_t *in_len
)
217 size_t left
, len
, list_len
, cert_len
, idx
;
219 struct x509_certificate
*chain
= NULL
, *last
= NULL
, *cert
;
222 if (ct
!= TLS_CONTENT_TYPE_HANDSHAKE
) {
223 wpa_printf(MSG_DEBUG
, "TLSv1: Expected Handshake; "
224 "received content type 0x%x", ct
);
225 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
226 TLS_ALERT_UNEXPECTED_MESSAGE
);
234 wpa_printf(MSG_DEBUG
, "TLSv1: Too short Certificate message "
235 "(len=%lu)", (unsigned long) left
);
236 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
, TLS_ALERT_DECODE_ERROR
);
241 len
= WPA_GET_BE24(pos
);
246 wpa_printf(MSG_DEBUG
, "TLSv1: Unexpected Certificate message "
247 "length (len=%lu != left=%lu)",
248 (unsigned long) len
, (unsigned long) left
);
249 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
, TLS_ALERT_DECODE_ERROR
);
253 if (type
== TLS_HANDSHAKE_TYPE_SERVER_KEY_EXCHANGE
)
254 return tls_process_server_key_exchange(conn
, ct
, in_data
,
256 if (type
== TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST
)
257 return tls_process_certificate_request(conn
, ct
, in_data
,
259 if (type
== TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE
)
260 return tls_process_server_hello_done(conn
, ct
, in_data
,
262 if (type
!= TLS_HANDSHAKE_TYPE_CERTIFICATE
) {
263 wpa_printf(MSG_DEBUG
, "TLSv1: Received unexpected handshake "
264 "message %d (expected Certificate/"
265 "ServerKeyExchange/CertificateRequest/"
266 "ServerHelloDone)", type
);
267 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
268 TLS_ALERT_UNEXPECTED_MESSAGE
);
272 wpa_printf(MSG_DEBUG
,
273 "TLSv1: Received Certificate (certificate_list len %lu)",
274 (unsigned long) len
);
277 * opaque ASN.1Cert<2^24-1>;
280 * ASN.1Cert certificate_list<1..2^24-1>;
287 wpa_printf(MSG_DEBUG
, "TLSv1: Too short Certificate "
288 "(left=%lu)", (unsigned long) left
);
289 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
, TLS_ALERT_DECODE_ERROR
);
293 list_len
= WPA_GET_BE24(pos
);
296 if ((size_t) (end
- pos
) != list_len
) {
297 wpa_printf(MSG_DEBUG
, "TLSv1: Unexpected certificate_list "
298 "length (len=%lu left=%lu)",
299 (unsigned long) list_len
,
300 (unsigned long) (end
- pos
));
301 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
, TLS_ALERT_DECODE_ERROR
);
308 wpa_printf(MSG_DEBUG
, "TLSv1: Failed to parse "
310 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
311 TLS_ALERT_DECODE_ERROR
);
312 x509_certificate_chain_free(chain
);
316 cert_len
= WPA_GET_BE24(pos
);
319 if ((size_t) (end
- pos
) < cert_len
) {
320 wpa_printf(MSG_DEBUG
, "TLSv1: Unexpected certificate "
321 "length (len=%lu left=%lu)",
322 (unsigned long) cert_len
,
323 (unsigned long) (end
- pos
));
324 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
325 TLS_ALERT_DECODE_ERROR
);
326 x509_certificate_chain_free(chain
);
330 wpa_printf(MSG_DEBUG
, "TLSv1: Certificate %lu (len %lu)",
331 (unsigned long) idx
, (unsigned long) cert_len
);
334 crypto_public_key_free(conn
->server_rsa_key
);
335 if (tls_parse_cert(pos
, cert_len
,
336 &conn
->server_rsa_key
)) {
337 wpa_printf(MSG_DEBUG
, "TLSv1: Failed to parse "
339 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
340 TLS_ALERT_BAD_CERTIFICATE
);
341 x509_certificate_chain_free(chain
);
346 cert
= x509_certificate_parse(pos
, cert_len
);
348 wpa_printf(MSG_DEBUG
, "TLSv1: Failed to parse "
350 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
351 TLS_ALERT_BAD_CERTIFICATE
);
352 x509_certificate_chain_free(chain
);
367 x509_certificate_chain_validate(conn
->cred
->trusted_certs
, chain
,
370 wpa_printf(MSG_DEBUG
, "TLSv1: Server certificate chain "
371 "validation failed (reason=%d)", reason
);
373 case X509_VALIDATE_BAD_CERTIFICATE
:
374 tls_reason
= TLS_ALERT_BAD_CERTIFICATE
;
376 case X509_VALIDATE_UNSUPPORTED_CERTIFICATE
:
377 tls_reason
= TLS_ALERT_UNSUPPORTED_CERTIFICATE
;
379 case X509_VALIDATE_CERTIFICATE_REVOKED
:
380 tls_reason
= TLS_ALERT_CERTIFICATE_REVOKED
;
382 case X509_VALIDATE_CERTIFICATE_EXPIRED
:
383 tls_reason
= TLS_ALERT_CERTIFICATE_EXPIRED
;
385 case X509_VALIDATE_CERTIFICATE_UNKNOWN
:
386 tls_reason
= TLS_ALERT_CERTIFICATE_UNKNOWN
;
388 case X509_VALIDATE_UNKNOWN_CA
:
389 tls_reason
= TLS_ALERT_UNKNOWN_CA
;
392 tls_reason
= TLS_ALERT_BAD_CERTIFICATE
;
395 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
, tls_reason
);
396 x509_certificate_chain_free(chain
);
400 x509_certificate_chain_free(chain
);
402 *in_len
= end
- in_data
;
404 conn
->state
= SERVER_KEY_EXCHANGE
;
410 static int tlsv1_process_diffie_hellman(struct tlsv1_client
*conn
,
411 const u8
*buf
, size_t len
)
415 tlsv1_client_free_dh(conn
);
422 conn
->dh_p_len
= WPA_GET_BE16(pos
);
424 if (conn
->dh_p_len
== 0 || end
- pos
< (int) conn
->dh_p_len
) {
425 wpa_printf(MSG_DEBUG
, "TLSv1: Invalid dh_p length %lu",
426 (unsigned long) conn
->dh_p_len
);
429 conn
->dh_p
= os_malloc(conn
->dh_p_len
);
430 if (conn
->dh_p
== NULL
)
432 os_memcpy(conn
->dh_p
, pos
, conn
->dh_p_len
);
433 pos
+= conn
->dh_p_len
;
434 wpa_hexdump(MSG_DEBUG
, "TLSv1: DH p (prime)",
435 conn
->dh_p
, conn
->dh_p_len
);
439 conn
->dh_g_len
= WPA_GET_BE16(pos
);
441 if (conn
->dh_g_len
== 0 || end
- pos
< (int) conn
->dh_g_len
)
443 conn
->dh_g
= os_malloc(conn
->dh_g_len
);
444 if (conn
->dh_g
== NULL
)
446 os_memcpy(conn
->dh_g
, pos
, conn
->dh_g_len
);
447 pos
+= conn
->dh_g_len
;
448 wpa_hexdump(MSG_DEBUG
, "TLSv1: DH g (generator)",
449 conn
->dh_g
, conn
->dh_g_len
);
450 if (conn
->dh_g_len
== 1 && conn
->dh_g
[0] < 2)
455 conn
->dh_ys_len
= WPA_GET_BE16(pos
);
457 if (conn
->dh_ys_len
== 0 || end
- pos
< (int) conn
->dh_ys_len
)
459 conn
->dh_ys
= os_malloc(conn
->dh_ys_len
);
460 if (conn
->dh_ys
== NULL
)
462 os_memcpy(conn
->dh_ys
, pos
, conn
->dh_ys_len
);
463 pos
+= conn
->dh_ys_len
;
464 wpa_hexdump(MSG_DEBUG
, "TLSv1: DH Ys (server's public value)",
465 conn
->dh_ys
, conn
->dh_ys_len
);
470 wpa_printf(MSG_DEBUG
, "TLSv1: Processing DH params failed");
471 tlsv1_client_free_dh(conn
);
476 static int tls_process_server_key_exchange(struct tlsv1_client
*conn
, u8 ct
,
477 const u8
*in_data
, size_t *in_len
)
482 const struct tls_cipher_suite
*suite
;
484 if (ct
!= TLS_CONTENT_TYPE_HANDSHAKE
) {
485 wpa_printf(MSG_DEBUG
, "TLSv1: Expected Handshake; "
486 "received content type 0x%x", ct
);
487 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
488 TLS_ALERT_UNEXPECTED_MESSAGE
);
496 wpa_printf(MSG_DEBUG
, "TLSv1: Too short ServerKeyExchange "
497 "(Left=%lu)", (unsigned long) left
);
498 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
, TLS_ALERT_DECODE_ERROR
);
503 len
= WPA_GET_BE24(pos
);
508 wpa_printf(MSG_DEBUG
, "TLSv1: Mismatch in ServerKeyExchange "
509 "length (len=%lu != left=%lu)",
510 (unsigned long) len
, (unsigned long) left
);
511 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
, TLS_ALERT_DECODE_ERROR
);
517 if (type
== TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST
)
518 return tls_process_certificate_request(conn
, ct
, in_data
,
520 if (type
== TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE
)
521 return tls_process_server_hello_done(conn
, ct
, in_data
,
523 if (type
!= TLS_HANDSHAKE_TYPE_SERVER_KEY_EXCHANGE
) {
524 wpa_printf(MSG_DEBUG
, "TLSv1: Received unexpected handshake "
525 "message %d (expected ServerKeyExchange/"
526 "CertificateRequest/ServerHelloDone)", type
);
527 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
528 TLS_ALERT_UNEXPECTED_MESSAGE
);
532 wpa_printf(MSG_DEBUG
, "TLSv1: Received ServerKeyExchange");
534 if (!tls_server_key_exchange_allowed(conn
->rl
.cipher_suite
)) {
535 wpa_printf(MSG_DEBUG
, "TLSv1: ServerKeyExchange not allowed "
536 "with the selected cipher suite");
537 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
538 TLS_ALERT_UNEXPECTED_MESSAGE
);
542 wpa_hexdump(MSG_DEBUG
, "TLSv1: ServerKeyExchange", pos
, len
);
543 suite
= tls_get_cipher_suite(conn
->rl
.cipher_suite
);
544 if (suite
&& suite
->key_exchange
== TLS_KEY_X_DH_anon
) {
545 if (tlsv1_process_diffie_hellman(conn
, pos
, len
) < 0) {
546 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
547 TLS_ALERT_DECODE_ERROR
);
551 wpa_printf(MSG_DEBUG
, "TLSv1: UnexpectedServerKeyExchange");
552 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
553 TLS_ALERT_UNEXPECTED_MESSAGE
);
557 *in_len
= end
- in_data
;
559 conn
->state
= SERVER_CERTIFICATE_REQUEST
;
565 static int tls_process_certificate_request(struct tlsv1_client
*conn
, u8 ct
,
566 const u8
*in_data
, size_t *in_len
)
572 if (ct
!= TLS_CONTENT_TYPE_HANDSHAKE
) {
573 wpa_printf(MSG_DEBUG
, "TLSv1: Expected Handshake; "
574 "received content type 0x%x", ct
);
575 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
576 TLS_ALERT_UNEXPECTED_MESSAGE
);
584 wpa_printf(MSG_DEBUG
, "TLSv1: Too short CertificateRequest "
585 "(left=%lu)", (unsigned long) left
);
586 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
, TLS_ALERT_DECODE_ERROR
);
591 len
= WPA_GET_BE24(pos
);
596 wpa_printf(MSG_DEBUG
, "TLSv1: Mismatch in CertificateRequest "
597 "length (len=%lu != left=%lu)",
598 (unsigned long) len
, (unsigned long) left
);
599 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
, TLS_ALERT_DECODE_ERROR
);
605 if (type
== TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE
)
606 return tls_process_server_hello_done(conn
, ct
, in_data
,
608 if (type
!= TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST
) {
609 wpa_printf(MSG_DEBUG
, "TLSv1: Received unexpected handshake "
610 "message %d (expected CertificateRequest/"
611 "ServerHelloDone)", type
);
612 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
613 TLS_ALERT_UNEXPECTED_MESSAGE
);
617 wpa_printf(MSG_DEBUG
, "TLSv1: Received CertificateRequest");
619 conn
->certificate_requested
= 1;
621 *in_len
= end
- in_data
;
623 conn
->state
= SERVER_HELLO_DONE
;
629 static int tls_process_server_hello_done(struct tlsv1_client
*conn
, u8 ct
,
630 const u8
*in_data
, size_t *in_len
)
636 if (ct
!= TLS_CONTENT_TYPE_HANDSHAKE
) {
637 wpa_printf(MSG_DEBUG
, "TLSv1: Expected Handshake; "
638 "received content type 0x%x", ct
);
639 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
640 TLS_ALERT_UNEXPECTED_MESSAGE
);
648 wpa_printf(MSG_DEBUG
, "TLSv1: Too short ServerHelloDone "
649 "(left=%lu)", (unsigned long) left
);
650 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
, TLS_ALERT_DECODE_ERROR
);
655 len
= WPA_GET_BE24(pos
);
660 wpa_printf(MSG_DEBUG
, "TLSv1: Mismatch in ServerHelloDone "
661 "length (len=%lu != left=%lu)",
662 (unsigned long) len
, (unsigned long) left
);
663 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
, TLS_ALERT_DECODE_ERROR
);
668 if (type
!= TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE
) {
669 wpa_printf(MSG_DEBUG
, "TLSv1: Received unexpected handshake "
670 "message %d (expected ServerHelloDone)", type
);
671 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
672 TLS_ALERT_UNEXPECTED_MESSAGE
);
676 wpa_printf(MSG_DEBUG
, "TLSv1: Received ServerHelloDone");
678 *in_len
= end
- in_data
;
680 conn
->state
= CLIENT_KEY_EXCHANGE
;
686 static int tls_process_server_change_cipher_spec(struct tlsv1_client
*conn
,
687 u8 ct
, const u8
*in_data
,
693 if (ct
!= TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC
) {
694 wpa_printf(MSG_DEBUG
, "TLSv1: Expected ChangeCipherSpec; "
695 "received content type 0x%x", ct
);
696 if (conn
->use_session_ticket
) {
698 wpa_printf(MSG_DEBUG
, "TLSv1: Server may have "
699 "rejected SessionTicket");
700 conn
->use_session_ticket
= 0;
702 /* Notify upper layers that SessionTicket failed */
703 res
= conn
->session_ticket_cb(
704 conn
->session_ticket_cb_ctx
, NULL
, 0, NULL
,
707 wpa_printf(MSG_DEBUG
, "TLSv1: SessionTicket "
708 "callback indicated failure");
709 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
710 TLS_ALERT_HANDSHAKE_FAILURE
);
714 conn
->state
= SERVER_CERTIFICATE
;
715 return tls_process_certificate(conn
, ct
, in_data
,
718 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
719 TLS_ALERT_UNEXPECTED_MESSAGE
);
727 wpa_printf(MSG_DEBUG
, "TLSv1: Too short ChangeCipherSpec");
728 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
, TLS_ALERT_DECODE_ERROR
);
732 if (*pos
!= TLS_CHANGE_CIPHER_SPEC
) {
733 wpa_printf(MSG_DEBUG
, "TLSv1: Expected ChangeCipherSpec; "
734 "received data 0x%x", *pos
);
735 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
736 TLS_ALERT_UNEXPECTED_MESSAGE
);
740 wpa_printf(MSG_DEBUG
, "TLSv1: Received ChangeCipherSpec");
741 if (tlsv1_record_change_read_cipher(&conn
->rl
) < 0) {
742 wpa_printf(MSG_DEBUG
, "TLSv1: Failed to change read cipher "
744 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
745 TLS_ALERT_INTERNAL_ERROR
);
749 *in_len
= pos
+ 1 - in_data
;
751 conn
->state
= SERVER_FINISHED
;
757 static int tls_process_server_finished(struct tlsv1_client
*conn
, u8 ct
,
758 const u8
*in_data
, size_t *in_len
)
761 size_t left
, len
, hlen
;
762 u8 verify_data
[TLS_VERIFY_DATA_LEN
];
763 u8 hash
[MD5_MAC_LEN
+ SHA1_MAC_LEN
];
765 if (ct
!= TLS_CONTENT_TYPE_HANDSHAKE
) {
766 wpa_printf(MSG_DEBUG
, "TLSv1: Expected Finished; "
767 "received content type 0x%x", ct
);
768 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
769 TLS_ALERT_UNEXPECTED_MESSAGE
);
777 wpa_printf(MSG_DEBUG
, "TLSv1: Too short record (left=%lu) for "
779 (unsigned long) left
);
780 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
781 TLS_ALERT_DECODE_ERROR
);
785 if (pos
[0] != TLS_HANDSHAKE_TYPE_FINISHED
) {
786 wpa_printf(MSG_DEBUG
, "TLSv1: Expected Finished; received "
787 "type 0x%x", pos
[0]);
788 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
789 TLS_ALERT_UNEXPECTED_MESSAGE
);
793 len
= WPA_GET_BE24(pos
+ 1);
799 wpa_printf(MSG_DEBUG
, "TLSv1: Too short buffer for Finished "
800 "(len=%lu > left=%lu)",
801 (unsigned long) len
, (unsigned long) left
);
802 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
803 TLS_ALERT_DECODE_ERROR
);
807 if (len
!= TLS_VERIFY_DATA_LEN
) {
808 wpa_printf(MSG_DEBUG
, "TLSv1: Unexpected verify_data length "
809 "in Finished: %lu (expected %d)",
810 (unsigned long) len
, TLS_VERIFY_DATA_LEN
);
811 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
812 TLS_ALERT_DECODE_ERROR
);
815 wpa_hexdump(MSG_MSGDUMP
, "TLSv1: verify_data in Finished",
816 pos
, TLS_VERIFY_DATA_LEN
);
819 if (conn
->verify
.md5_server
== NULL
||
820 crypto_hash_finish(conn
->verify
.md5_server
, hash
, &hlen
) < 0) {
821 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
822 TLS_ALERT_INTERNAL_ERROR
);
823 conn
->verify
.md5_server
= NULL
;
824 crypto_hash_finish(conn
->verify
.sha1_server
, NULL
, NULL
);
825 conn
->verify
.sha1_server
= NULL
;
828 conn
->verify
.md5_server
= NULL
;
830 if (conn
->verify
.sha1_server
== NULL
||
831 crypto_hash_finish(conn
->verify
.sha1_server
, hash
+ MD5_MAC_LEN
,
833 conn
->verify
.sha1_server
= NULL
;
834 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
835 TLS_ALERT_INTERNAL_ERROR
);
838 conn
->verify
.sha1_server
= NULL
;
840 if (tls_prf(conn
->master_secret
, TLS_MASTER_SECRET_LEN
,
841 "server finished", hash
, MD5_MAC_LEN
+ SHA1_MAC_LEN
,
842 verify_data
, TLS_VERIFY_DATA_LEN
)) {
843 wpa_printf(MSG_DEBUG
, "TLSv1: Failed to derive verify_data");
844 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
845 TLS_ALERT_DECRYPT_ERROR
);
848 wpa_hexdump_key(MSG_DEBUG
, "TLSv1: verify_data (server)",
849 verify_data
, TLS_VERIFY_DATA_LEN
);
851 if (os_memcmp(pos
, verify_data
, TLS_VERIFY_DATA_LEN
) != 0) {
852 wpa_printf(MSG_INFO
, "TLSv1: Mismatch in verify_data");
856 wpa_printf(MSG_DEBUG
, "TLSv1: Received Finished");
858 *in_len
= end
- in_data
;
860 conn
->state
= (conn
->session_resumed
|| conn
->use_session_ticket
) ?
861 CHANGE_CIPHER_SPEC
: ACK_FINISHED
;
867 static int tls_process_application_data(struct tlsv1_client
*conn
, u8 ct
,
868 const u8
*in_data
, size_t *in_len
,
869 u8
**out_data
, size_t *out_len
)
874 if (ct
!= TLS_CONTENT_TYPE_APPLICATION_DATA
) {
875 wpa_printf(MSG_DEBUG
, "TLSv1: Expected Application Data; "
876 "received content type 0x%x", ct
);
877 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
878 TLS_ALERT_UNEXPECTED_MESSAGE
);
885 wpa_hexdump(MSG_DEBUG
, "TLSv1: Application Data included in Handshake",
888 *out_data
= os_malloc(left
);
890 os_memcpy(*out_data
, pos
, left
);
898 int tlsv1_client_process_handshake(struct tlsv1_client
*conn
, u8 ct
,
899 const u8
*buf
, size_t *len
,
900 u8
**out_data
, size_t *out_len
)
902 if (ct
== TLS_CONTENT_TYPE_ALERT
) {
904 wpa_printf(MSG_DEBUG
, "TLSv1: Alert underflow");
905 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
906 TLS_ALERT_DECODE_ERROR
);
909 wpa_printf(MSG_DEBUG
, "TLSv1: Received alert %d:%d",
912 conn
->state
= FAILED
;
916 if (ct
== TLS_CONTENT_TYPE_HANDSHAKE
&& *len
>= 4 &&
917 buf
[0] == TLS_HANDSHAKE_TYPE_HELLO_REQUEST
) {
918 size_t hr_len
= WPA_GET_BE24(buf
+ 1);
919 if (hr_len
> *len
- 4) {
920 wpa_printf(MSG_DEBUG
, "TLSv1: HelloRequest underflow");
921 tls_alert(conn
, TLS_ALERT_LEVEL_FATAL
,
922 TLS_ALERT_DECODE_ERROR
);
925 wpa_printf(MSG_DEBUG
, "TLSv1: Ignored HelloRequest");
930 switch (conn
->state
) {
932 if (tls_process_server_hello(conn
, ct
, buf
, len
))
935 case SERVER_CERTIFICATE
:
936 if (tls_process_certificate(conn
, ct
, buf
, len
))
939 case SERVER_KEY_EXCHANGE
:
940 if (tls_process_server_key_exchange(conn
, ct
, buf
, len
))
943 case SERVER_CERTIFICATE_REQUEST
:
944 if (tls_process_certificate_request(conn
, ct
, buf
, len
))
947 case SERVER_HELLO_DONE
:
948 if (tls_process_server_hello_done(conn
, ct
, buf
, len
))
951 case SERVER_CHANGE_CIPHER_SPEC
:
952 if (tls_process_server_change_cipher_spec(conn
, ct
, buf
, len
))
955 case SERVER_FINISHED
:
956 if (tls_process_server_finished(conn
, ct
, buf
, len
))
961 tls_process_application_data(conn
, ct
, buf
, len
, out_data
,
966 wpa_printf(MSG_DEBUG
, "TLSv1: Unexpected state %d "
967 "while processing received message",
972 if (ct
== TLS_CONTENT_TYPE_HANDSHAKE
)
973 tls_verify_hash_add(&conn
->verify
, buf
, *len
);