Merge branch 'vendor/OPENSSL'
[dragonfly.git] / contrib / hostapd / src / tls / tlsv1_client_read.c
1 /*
2  * TLSv1 client - read handshake message
3  * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi>
4  *
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.
8  *
9  * Alternatively, this software may be distributed under the terms of BSD
10  * license.
11  *
12  * See README and COPYING for more details.
13  */
14
15 #include "includes.h"
16
17 #include "common.h"
18 #include "md5.h"
19 #include "sha1.h"
20 #include "x509v3.h"
21 #include "tls.h"
22 #include "tlsv1_common.h"
23 #include "tlsv1_record.h"
24 #include "tlsv1_client.h"
25 #include "tlsv1_client_i.h"
26
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);
33
34
35 static int tls_process_server_hello(struct tlsv1_client *conn, u8 ct,
36                                     const u8 *in_data, size_t *in_len)
37 {
38         const u8 *pos, *end;
39         size_t left, len, i;
40         u16 cipher_suite;
41
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);
47                 return -1;
48         }
49
50         pos = in_data;
51         left = *in_len;
52
53         if (left < 4)
54                 goto decode_error;
55
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);
62                 return -1;
63         }
64         wpa_printf(MSG_DEBUG, "TLSv1: Received ServerHello");
65         pos++;
66         /* uint24 length */
67         len = WPA_GET_BE24(pos);
68         pos += 3;
69         left -= 4;
70
71         if (len > left)
72                 goto decode_error;
73
74         /* body - ServerHello */
75
76         wpa_hexdump(MSG_MSGDUMP, "TLSv1: ServerHello", pos, len);
77         end = pos + len;
78
79         /* ProtocolVersion server_version */
80         if (end - pos < 2)
81                 goto decode_error;
82         if (WPA_GET_BE16(pos) != TLS_VERSION) {
83                 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected protocol version in "
84                            "ServerHello");
85                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
86                           TLS_ALERT_PROTOCOL_VERSION);
87                 return -1;
88         }
89         pos += 2;
90
91         /* Random random */
92         if (end - pos < TLS_RANDOM_LEN)
93                 goto decode_error;
94
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);
99
100         /* SessionID session_id */
101         if (end - pos < 1)
102                 goto decode_error;
103         if (end - pos < 1 + *pos || *pos > TLS_SESSION_ID_MAX_LEN)
104                 goto decode_error;
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;
110         } else {
111                 conn->session_id_len = *pos;
112                 pos++;
113                 os_memcpy(conn->session_id, pos, conn->session_id_len);
114                 pos += conn->session_id_len;
115         }
116         wpa_hexdump(MSG_MSGDUMP, "TLSv1: session_id",
117                     conn->session_id, conn->session_id_len);
118
119         /* CipherSuite cipher_suite */
120         if (end - pos < 2)
121                 goto decode_error;
122         cipher_suite = WPA_GET_BE16(pos);
123         pos += 2;
124         for (i = 0; i < conn->num_cipher_suites; i++) {
125                 if (cipher_suite == conn->cipher_suites[i])
126                         break;
127         }
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);
133                 return -1;
134         }
135
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);
142                 return -1;
143         }
144
145         if (tlsv1_record_set_cipher_suite(&conn->rl, cipher_suite) < 0) {
146                 wpa_printf(MSG_DEBUG, "TLSv1: Failed to set CipherSuite for "
147                            "record layer");
148                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
149                           TLS_ALERT_INTERNAL_ERROR);
150                 return -1;
151         }
152
153         conn->prev_cipher_suite = cipher_suite;
154
155         /* CompressionMethod compression_method */
156         if (end - pos < 1)
157                 goto decode_error;
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);
163                 return -1;
164         }
165         pos++;
166
167         if (end != pos) {
168                 /* TODO: ServerHello extensions */
169                 wpa_hexdump(MSG_DEBUG, "TLSv1: Unexpected extra data in the "
170                             "end of ServerHello", pos, end - pos);
171                 goto decode_error;
172         }
173
174         if (conn->session_ticket_included && conn->session_ticket_cb) {
175                 /* TODO: include SessionTicket extension if one was included in
176                  * ServerHello */
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);
181                 if (res < 0) {
182                         wpa_printf(MSG_DEBUG, "TLSv1: SessionTicket callback "
183                                    "indicated failure");
184                         tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
185                                   TLS_ALERT_HANDSHAKE_FAILURE);
186                         return -1;
187                 }
188                 conn->use_session_ticket = !!res;
189         }
190
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);
196                 return -1;
197         }
198
199         *in_len = end - in_data;
200
201         conn->state = (conn->session_resumed || conn->use_session_ticket) ?
202                 SERVER_CHANGE_CIPHER_SPEC : SERVER_CERTIFICATE;
203
204         return 0;
205
206 decode_error:
207         wpa_printf(MSG_DEBUG, "TLSv1: Failed to decode ServerHello");
208         tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
209         return -1;
210 }
211
212
213 static int tls_process_certificate(struct tlsv1_client *conn, u8 ct,
214                                    const u8 *in_data, size_t *in_len)
215 {
216         const u8 *pos, *end;
217         size_t left, len, list_len, cert_len, idx;
218         u8 type;
219         struct x509_certificate *chain = NULL, *last = NULL, *cert;
220         int reason;
221
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);
227                 return -1;
228         }
229
230         pos = in_data;
231         left = *in_len;
232
233         if (left < 4) {
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);
237                 return -1;
238         }
239
240         type = *pos++;
241         len = WPA_GET_BE24(pos);
242         pos += 3;
243         left -= 4;
244
245         if (len > left) {
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);
250                 return -1;
251         }
252
253         if (type == TLS_HANDSHAKE_TYPE_SERVER_KEY_EXCHANGE)
254                 return tls_process_server_key_exchange(conn, ct, in_data,
255                                                        in_len);
256         if (type == TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST)
257                 return tls_process_certificate_request(conn, ct, in_data,
258                                                        in_len);
259         if (type == TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE)
260                 return tls_process_server_hello_done(conn, ct, in_data,
261                                                      in_len);
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);
269                 return -1;
270         }
271
272         wpa_printf(MSG_DEBUG,
273                    "TLSv1: Received Certificate (certificate_list len %lu)",
274                    (unsigned long) len);
275
276         /*
277          * opaque ASN.1Cert<2^24-1>;
278          *
279          * struct {
280          *     ASN.1Cert certificate_list<1..2^24-1>;
281          * } Certificate;
282          */
283
284         end = pos + len;
285
286         if (end - pos < 3) {
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);
290                 return -1;
291         }
292
293         list_len = WPA_GET_BE24(pos);
294         pos += 3;
295
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);
302                 return -1;
303         }
304
305         idx = 0;
306         while (pos < end) {
307                 if (end - pos < 3) {
308                         wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse "
309                                    "certificate_list");
310                         tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
311                                   TLS_ALERT_DECODE_ERROR);
312                         x509_certificate_chain_free(chain);
313                         return -1;
314                 }
315
316                 cert_len = WPA_GET_BE24(pos);
317                 pos += 3;
318
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);
327                         return -1;
328                 }
329
330                 wpa_printf(MSG_DEBUG, "TLSv1: Certificate %lu (len %lu)",
331                            (unsigned long) idx, (unsigned long) cert_len);
332
333                 if (idx == 0) {
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 "
338                                            "the certificate");
339                                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
340                                           TLS_ALERT_BAD_CERTIFICATE);
341                                 x509_certificate_chain_free(chain);
342                                 return -1;
343                         }
344                 }
345
346                 cert = x509_certificate_parse(pos, cert_len);
347                 if (cert == NULL) {
348                         wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse "
349                                    "the certificate");
350                         tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
351                                   TLS_ALERT_BAD_CERTIFICATE);
352                         x509_certificate_chain_free(chain);
353                         return -1;
354                 }
355
356                 if (last == NULL)
357                         chain = cert;
358                 else
359                         last->next = cert;
360                 last = cert;
361
362                 idx++;
363                 pos += cert_len;
364         }
365
366         if (conn->cred &&
367             x509_certificate_chain_validate(conn->cred->trusted_certs, chain,
368                                             &reason) < 0) {
369                 int tls_reason;
370                 wpa_printf(MSG_DEBUG, "TLSv1: Server certificate chain "
371                            "validation failed (reason=%d)", reason);
372                 switch (reason) {
373                 case X509_VALIDATE_BAD_CERTIFICATE:
374                         tls_reason = TLS_ALERT_BAD_CERTIFICATE;
375                         break;
376                 case X509_VALIDATE_UNSUPPORTED_CERTIFICATE:
377                         tls_reason = TLS_ALERT_UNSUPPORTED_CERTIFICATE;
378                         break;
379                 case X509_VALIDATE_CERTIFICATE_REVOKED:
380                         tls_reason = TLS_ALERT_CERTIFICATE_REVOKED;
381                         break;
382                 case X509_VALIDATE_CERTIFICATE_EXPIRED:
383                         tls_reason = TLS_ALERT_CERTIFICATE_EXPIRED;
384                         break;
385                 case X509_VALIDATE_CERTIFICATE_UNKNOWN:
386                         tls_reason = TLS_ALERT_CERTIFICATE_UNKNOWN;
387                         break;
388                 case X509_VALIDATE_UNKNOWN_CA:
389                         tls_reason = TLS_ALERT_UNKNOWN_CA;
390                         break;
391                 default:
392                         tls_reason = TLS_ALERT_BAD_CERTIFICATE;
393                         break;
394                 }
395                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, tls_reason);
396                 x509_certificate_chain_free(chain);
397                 return -1;
398         }
399
400         x509_certificate_chain_free(chain);
401
402         *in_len = end - in_data;
403
404         conn->state = SERVER_KEY_EXCHANGE;
405
406         return 0;
407 }
408
409
410 static int tlsv1_process_diffie_hellman(struct tlsv1_client *conn,
411                                         const u8 *buf, size_t len)
412 {
413         const u8 *pos, *end;
414
415         tlsv1_client_free_dh(conn);
416
417         pos = buf;
418         end = buf + len;
419
420         if (end - pos < 3)
421                 goto fail;
422         conn->dh_p_len = WPA_GET_BE16(pos);
423         pos += 2;
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);
427                 goto fail;
428         }
429         conn->dh_p = os_malloc(conn->dh_p_len);
430         if (conn->dh_p == NULL)
431                 goto fail;
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);
436
437         if (end - pos < 3)
438                 goto fail;
439         conn->dh_g_len = WPA_GET_BE16(pos);
440         pos += 2;
441         if (conn->dh_g_len == 0 || end - pos < (int) conn->dh_g_len)
442                 goto fail;
443         conn->dh_g = os_malloc(conn->dh_g_len);
444         if (conn->dh_g == NULL)
445                 goto fail;
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)
451                 goto fail;
452
453         if (end - pos < 3)
454                 goto fail;
455         conn->dh_ys_len = WPA_GET_BE16(pos);
456         pos += 2;
457         if (conn->dh_ys_len == 0 || end - pos < (int) conn->dh_ys_len)
458                 goto fail;
459         conn->dh_ys = os_malloc(conn->dh_ys_len);
460         if (conn->dh_ys == NULL)
461                 goto fail;
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);
466
467         return 0;
468
469 fail:
470         wpa_printf(MSG_DEBUG, "TLSv1: Processing DH params failed");
471         tlsv1_client_free_dh(conn);
472         return -1;
473 }
474
475
476 static int tls_process_server_key_exchange(struct tlsv1_client *conn, u8 ct,
477                                            const u8 *in_data, size_t *in_len)
478 {
479         const u8 *pos, *end;
480         size_t left, len;
481         u8 type;
482         const struct tls_cipher_suite *suite;
483
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);
489                 return -1;
490         }
491
492         pos = in_data;
493         left = *in_len;
494
495         if (left < 4) {
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);
499                 return -1;
500         }
501
502         type = *pos++;
503         len = WPA_GET_BE24(pos);
504         pos += 3;
505         left -= 4;
506
507         if (len > left) {
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);
512                 return -1;
513         }
514
515         end = pos + len;
516
517         if (type == TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST)
518                 return tls_process_certificate_request(conn, ct, in_data,
519                                                        in_len);
520         if (type == TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE)
521                 return tls_process_server_hello_done(conn, ct, in_data,
522                                                      in_len);
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);
529                 return -1;
530         }
531
532         wpa_printf(MSG_DEBUG, "TLSv1: Received ServerKeyExchange");
533
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);
539                 return -1;
540         }
541
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);
548                         return -1;
549                 }
550         } else {
551                 wpa_printf(MSG_DEBUG, "TLSv1: UnexpectedServerKeyExchange");
552                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
553                           TLS_ALERT_UNEXPECTED_MESSAGE);
554                 return -1;
555         }
556
557         *in_len = end - in_data;
558
559         conn->state = SERVER_CERTIFICATE_REQUEST;
560
561         return 0;
562 }
563
564
565 static int tls_process_certificate_request(struct tlsv1_client *conn, u8 ct,
566                                            const u8 *in_data, size_t *in_len)
567 {
568         const u8 *pos, *end;
569         size_t left, len;
570         u8 type;
571
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);
577                 return -1;
578         }
579
580         pos = in_data;
581         left = *in_len;
582
583         if (left < 4) {
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);
587                 return -1;
588         }
589
590         type = *pos++;
591         len = WPA_GET_BE24(pos);
592         pos += 3;
593         left -= 4;
594
595         if (len > left) {
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);
600                 return -1;
601         }
602
603         end = pos + len;
604
605         if (type == TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE)
606                 return tls_process_server_hello_done(conn, ct, in_data,
607                                                      in_len);
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);
614                 return -1;
615         }
616
617         wpa_printf(MSG_DEBUG, "TLSv1: Received CertificateRequest");
618
619         conn->certificate_requested = 1;
620
621         *in_len = end - in_data;
622
623         conn->state = SERVER_HELLO_DONE;
624
625         return 0;
626 }
627
628
629 static int tls_process_server_hello_done(struct tlsv1_client *conn, u8 ct,
630                                          const u8 *in_data, size_t *in_len)
631 {
632         const u8 *pos, *end;
633         size_t left, len;
634         u8 type;
635
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);
641                 return -1;
642         }
643
644         pos = in_data;
645         left = *in_len;
646
647         if (left < 4) {
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);
651                 return -1;
652         }
653
654         type = *pos++;
655         len = WPA_GET_BE24(pos);
656         pos += 3;
657         left -= 4;
658
659         if (len > left) {
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);
664                 return -1;
665         }
666         end = pos + len;
667
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);
673                 return -1;
674         }
675
676         wpa_printf(MSG_DEBUG, "TLSv1: Received ServerHelloDone");
677
678         *in_len = end - in_data;
679
680         conn->state = CLIENT_KEY_EXCHANGE;
681
682         return 0;
683 }
684
685
686 static int tls_process_server_change_cipher_spec(struct tlsv1_client *conn,
687                                                  u8 ct, const u8 *in_data,
688                                                  size_t *in_len)
689 {
690         const u8 *pos;
691         size_t left;
692
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) {
697                         int res;
698                         wpa_printf(MSG_DEBUG, "TLSv1: Server may have "
699                                    "rejected SessionTicket");
700                         conn->use_session_ticket = 0;
701
702                         /* Notify upper layers that SessionTicket failed */
703                         res = conn->session_ticket_cb(
704                                 conn->session_ticket_cb_ctx, NULL, 0, NULL,
705                                 NULL, NULL);
706                         if (res < 0) {
707                                 wpa_printf(MSG_DEBUG, "TLSv1: SessionTicket "
708                                            "callback indicated failure");
709                                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
710                                           TLS_ALERT_HANDSHAKE_FAILURE);
711                                 return -1;
712                         }
713
714                         conn->state = SERVER_CERTIFICATE;
715                         return tls_process_certificate(conn, ct, in_data,
716                                                        in_len);
717                 }
718                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
719                           TLS_ALERT_UNEXPECTED_MESSAGE);
720                 return -1;
721         }
722
723         pos = in_data;
724         left = *in_len;
725
726         if (left < 1) {
727                 wpa_printf(MSG_DEBUG, "TLSv1: Too short ChangeCipherSpec");
728                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
729                 return -1;
730         }
731
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);
737                 return -1;
738         }
739
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 "
743                            "for record layer");
744                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
745                           TLS_ALERT_INTERNAL_ERROR);
746                 return -1;
747         }
748
749         *in_len = pos + 1 - in_data;
750
751         conn->state = SERVER_FINISHED;
752
753         return 0;
754 }
755
756
757 static int tls_process_server_finished(struct tlsv1_client *conn, u8 ct,
758                                        const u8 *in_data, size_t *in_len)
759 {
760         const u8 *pos, *end;
761         size_t left, len, hlen;
762         u8 verify_data[TLS_VERIFY_DATA_LEN];
763         u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN];
764
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);
770                 return -1;
771         }
772
773         pos = in_data;
774         left = *in_len;
775
776         if (left < 4) {
777                 wpa_printf(MSG_DEBUG, "TLSv1: Too short record (left=%lu) for "
778                            "Finished",
779                            (unsigned long) left);
780                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
781                           TLS_ALERT_DECODE_ERROR);
782                 return -1;
783         }
784
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);
790                 return -1;
791         }
792
793         len = WPA_GET_BE24(pos + 1);
794
795         pos += 4;
796         left -= 4;
797
798         if (len > left) {
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);
804                 return -1;
805         }
806         end = pos + len;
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);
813                 return -1;
814         }
815         wpa_hexdump(MSG_MSGDUMP, "TLSv1: verify_data in Finished",
816                     pos, TLS_VERIFY_DATA_LEN);
817
818         hlen = MD5_MAC_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;
826                 return -1;
827         }
828         conn->verify.md5_server = NULL;
829         hlen = SHA1_MAC_LEN;
830         if (conn->verify.sha1_server == NULL ||
831             crypto_hash_finish(conn->verify.sha1_server, hash + MD5_MAC_LEN,
832                                &hlen) < 0) {
833                 conn->verify.sha1_server = NULL;
834                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
835                           TLS_ALERT_INTERNAL_ERROR);
836                 return -1;
837         }
838         conn->verify.sha1_server = NULL;
839
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);
846                 return -1;
847         }
848         wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (server)",
849                         verify_data, TLS_VERIFY_DATA_LEN);
850
851         if (os_memcmp(pos, verify_data, TLS_VERIFY_DATA_LEN) != 0) {
852                 wpa_printf(MSG_INFO, "TLSv1: Mismatch in verify_data");
853                 return -1;
854         }
855
856         wpa_printf(MSG_DEBUG, "TLSv1: Received Finished");
857
858         *in_len = end - in_data;
859
860         conn->state = (conn->session_resumed || conn->use_session_ticket) ?
861                 CHANGE_CIPHER_SPEC : ACK_FINISHED;
862
863         return 0;
864 }
865
866
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)
870 {
871         const u8 *pos;
872         size_t left;
873
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);
879                 return -1;
880         }
881
882         pos = in_data;
883         left = *in_len;
884
885         wpa_hexdump(MSG_DEBUG, "TLSv1: Application Data included in Handshake",
886                     pos, left);
887
888         *out_data = os_malloc(left);
889         if (*out_data) {
890                 os_memcpy(*out_data, pos, left);
891                 *out_len = left;
892         }
893
894         return 0;
895 }
896
897
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)
901 {
902         if (ct == TLS_CONTENT_TYPE_ALERT) {
903                 if (*len < 2) {
904                         wpa_printf(MSG_DEBUG, "TLSv1: Alert underflow");
905                         tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
906                                   TLS_ALERT_DECODE_ERROR);
907                         return -1;
908                 }
909                 wpa_printf(MSG_DEBUG, "TLSv1: Received alert %d:%d",
910                            buf[0], buf[1]);
911                 *len = 2;
912                 conn->state = FAILED;
913                 return -1;
914         }
915
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);
923                         return -1;
924                 }
925                 wpa_printf(MSG_DEBUG, "TLSv1: Ignored HelloRequest");
926                 *len = 4 + hr_len;
927                 return 0;
928         }
929
930         switch (conn->state) {
931         case SERVER_HELLO:
932                 if (tls_process_server_hello(conn, ct, buf, len))
933                         return -1;
934                 break;
935         case SERVER_CERTIFICATE:
936                 if (tls_process_certificate(conn, ct, buf, len))
937                         return -1;
938                 break;
939         case SERVER_KEY_EXCHANGE:
940                 if (tls_process_server_key_exchange(conn, ct, buf, len))
941                         return -1;
942                 break;
943         case SERVER_CERTIFICATE_REQUEST:
944                 if (tls_process_certificate_request(conn, ct, buf, len))
945                         return -1;
946                 break;
947         case SERVER_HELLO_DONE:
948                 if (tls_process_server_hello_done(conn, ct, buf, len))
949                         return -1;
950                 break;
951         case SERVER_CHANGE_CIPHER_SPEC:
952                 if (tls_process_server_change_cipher_spec(conn, ct, buf, len))
953                         return -1;
954                 break;
955         case SERVER_FINISHED:
956                 if (tls_process_server_finished(conn, ct, buf, len))
957                         return -1;
958                 break;
959         case ACK_FINISHED:
960                 if (out_data &&
961                     tls_process_application_data(conn, ct, buf, len, out_data,
962                                                  out_len))
963                         return -1;
964                 break;
965         default:
966                 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected state %d "
967                            "while processing received message",
968                            conn->state);
969                 return -1;
970         }
971
972         if (ct == TLS_CONTENT_TYPE_HANDSHAKE)
973                 tls_verify_hash_add(&conn->verify, buf, *len);
974
975         return 0;
976 }