Merge branch 'vendor/GCC50'
[dragonfly.git] / contrib / hostapd / src / tls / tlsv1_client_read.c
1 /*
2  * TLSv1 client - read handshake message
3  * Copyright (c) 2006-2011, Jouni Malinen <j@w1.fi>
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8
9 #include "includes.h"
10
11 #include "common.h"
12 #include "crypto/md5.h"
13 #include "crypto/sha1.h"
14 #include "crypto/sha256.h"
15 #include "crypto/tls.h"
16 #include "x509v3.h"
17 #include "tlsv1_common.h"
18 #include "tlsv1_record.h"
19 #include "tlsv1_client.h"
20 #include "tlsv1_client_i.h"
21
22 static int tls_process_server_key_exchange(struct tlsv1_client *conn, u8 ct,
23                                            const u8 *in_data, size_t *in_len);
24 static int tls_process_certificate_request(struct tlsv1_client *conn, u8 ct,
25                                            const u8 *in_data, size_t *in_len);
26 static int tls_process_server_hello_done(struct tlsv1_client *conn, u8 ct,
27                                          const u8 *in_data, size_t *in_len);
28
29
30 static 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;
36         u16 tls_version;
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;
78         tls_version = WPA_GET_BE16(pos);
79         if (!tls_version_ok(tls_version)) {
80                 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected protocol version in "
81                            "ServerHello %u.%u", pos[0], pos[1]);
82                 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
83                           TLS_ALERT_PROTOCOL_VERSION);
84                 return -1;
85         }
86         pos += 2;
87
88         wpa_printf(MSG_DEBUG, "TLSv1: Using TLS v%s",
89                    tls_version_str(tls_version));
90         conn->rl.tls_version = tls_version;
91
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
207 decode_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
214 static 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,
369                                             &reason, conn->disable_time_checks)
370             < 0) {
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
412 static 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
471 fail:
472         wpa_printf(MSG_DEBUG, "TLSv1: Processing DH params failed");
473         tlsv1_client_free_dh(conn);
474         return -1;
475 }
476
477
478 static 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
567 static 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
631 static 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
688 static 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
759 static 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
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
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;
856         hlen = MD5_MAC_LEN + SHA1_MAC_LEN;
857
858 #ifdef CONFIG_TLSV12
859         }
860 #endif /* CONFIG_TLSV12 */
861
862         if (tls_prf(conn->rl.tls_version,
863                     conn->master_secret, TLS_MASTER_SECRET_LEN,
864                     "server finished", hash, hlen,
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
890 static 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
921 int 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 }