blob: 443c028fb47b94f72f392b6374512ec69d8528fd [file] [log] [blame]
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001/*
2 * TLSv1 server - read handshake message
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08003 * Copyright (c) 2006-2011, Jouni Malinen <j@w1.fi>
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07004 *
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 "crypto/md5.h"
19#include "crypto/sha1.h"
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -080020#include "crypto/sha256.h"
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070021#include "crypto/tls.h"
22#include "x509v3.h"
23#include "tlsv1_common.h"
24#include "tlsv1_record.h"
25#include "tlsv1_server.h"
26#include "tlsv1_server_i.h"
27
28
29static int tls_process_client_key_exchange(struct tlsv1_server *conn, u8 ct,
30 const u8 *in_data, size_t *in_len);
31static int tls_process_change_cipher_spec(struct tlsv1_server *conn,
32 u8 ct, const u8 *in_data,
33 size_t *in_len);
34
35
36static int tls_process_client_hello(struct tlsv1_server *conn, u8 ct,
37 const u8 *in_data, size_t *in_len)
38{
39 const u8 *pos, *end, *c;
40 size_t left, len, i, j;
41 u16 cipher_suite;
42 u16 num_suites;
43 int compr_null_found;
44 u16 ext_type, ext_len;
45
46 if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
47 wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
48 "received content type 0x%x", ct);
49 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
50 TLS_ALERT_UNEXPECTED_MESSAGE);
51 return -1;
52 }
53
54 pos = in_data;
55 left = *in_len;
56
57 if (left < 4)
58 goto decode_error;
59
60 /* HandshakeType msg_type */
61 if (*pos != TLS_HANDSHAKE_TYPE_CLIENT_HELLO) {
62 wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
63 "message %d (expected ClientHello)", *pos);
64 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
65 TLS_ALERT_UNEXPECTED_MESSAGE);
66 return -1;
67 }
68 wpa_printf(MSG_DEBUG, "TLSv1: Received ClientHello");
69 pos++;
70 /* uint24 length */
71 len = WPA_GET_BE24(pos);
72 pos += 3;
73 left -= 4;
74
75 if (len > left)
76 goto decode_error;
77
78 /* body - ClientHello */
79
80 wpa_hexdump(MSG_MSGDUMP, "TLSv1: ClientHello", pos, len);
81 end = pos + len;
82
83 /* ProtocolVersion client_version */
84 if (end - pos < 2)
85 goto decode_error;
86 conn->client_version = WPA_GET_BE16(pos);
87 wpa_printf(MSG_DEBUG, "TLSv1: Client version %d.%d",
88 conn->client_version >> 8, conn->client_version & 0xff);
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -080089 if (conn->client_version < TLS_VERSION_1) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070090 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected protocol version in "
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -080091 "ClientHello %u.%u",
92 conn->client_version >> 8,
93 conn->client_version & 0xff);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -070094 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
95 TLS_ALERT_PROTOCOL_VERSION);
96 return -1;
97 }
98 pos += 2;
99
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800100 if (TLS_VERSION == TLS_VERSION_1)
101 conn->rl.tls_version = TLS_VERSION_1;
102#ifdef CONFIG_TLSV12
103 else if (conn->client_version >= TLS_VERSION_1_2)
104 conn->rl.tls_version = TLS_VERSION_1_2;
105#endif /* CONFIG_TLSV12 */
106 else if (conn->client_version > TLS_VERSION_1_1)
107 conn->rl.tls_version = TLS_VERSION_1_1;
108 else
109 conn->rl.tls_version = conn->client_version;
110 wpa_printf(MSG_DEBUG, "TLSv1: Using TLS v%s",
111 tls_version_str(conn->rl.tls_version));
112
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700113 /* Random random */
114 if (end - pos < TLS_RANDOM_LEN)
115 goto decode_error;
116
117 os_memcpy(conn->client_random, pos, TLS_RANDOM_LEN);
118 pos += TLS_RANDOM_LEN;
119 wpa_hexdump(MSG_MSGDUMP, "TLSv1: client_random",
120 conn->client_random, TLS_RANDOM_LEN);
121
122 /* SessionID session_id */
123 if (end - pos < 1)
124 goto decode_error;
125 if (end - pos < 1 + *pos || *pos > TLS_SESSION_ID_MAX_LEN)
126 goto decode_error;
127 wpa_hexdump(MSG_MSGDUMP, "TLSv1: client session_id", pos + 1, *pos);
128 pos += 1 + *pos;
129 /* TODO: add support for session resumption */
130
131 /* CipherSuite cipher_suites<2..2^16-1> */
132 if (end - pos < 2)
133 goto decode_error;
134 num_suites = WPA_GET_BE16(pos);
135 pos += 2;
136 if (end - pos < num_suites)
137 goto decode_error;
138 wpa_hexdump(MSG_MSGDUMP, "TLSv1: client cipher suites",
139 pos, num_suites);
140 if (num_suites & 1)
141 goto decode_error;
142 num_suites /= 2;
143
144 cipher_suite = 0;
145 for (i = 0; !cipher_suite && i < conn->num_cipher_suites; i++) {
146 c = pos;
147 for (j = 0; j < num_suites; j++) {
148 u16 tmp = WPA_GET_BE16(c);
149 c += 2;
150 if (!cipher_suite && tmp == conn->cipher_suites[i]) {
151 cipher_suite = tmp;
152 break;
153 }
154 }
155 }
156 pos += num_suites * 2;
157 if (!cipher_suite) {
158 wpa_printf(MSG_INFO, "TLSv1: No supported cipher suite "
159 "available");
160 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
161 TLS_ALERT_ILLEGAL_PARAMETER);
162 return -1;
163 }
164
165 if (tlsv1_record_set_cipher_suite(&conn->rl, cipher_suite) < 0) {
166 wpa_printf(MSG_DEBUG, "TLSv1: Failed to set CipherSuite for "
167 "record layer");
168 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
169 TLS_ALERT_INTERNAL_ERROR);
170 return -1;
171 }
172
173 conn->cipher_suite = cipher_suite;
174
175 /* CompressionMethod compression_methods<1..2^8-1> */
176 if (end - pos < 1)
177 goto decode_error;
178 num_suites = *pos++;
179 if (end - pos < num_suites)
180 goto decode_error;
181 wpa_hexdump(MSG_MSGDUMP, "TLSv1: client compression_methods",
182 pos, num_suites);
183 compr_null_found = 0;
184 for (i = 0; i < num_suites; i++) {
185 if (*pos++ == TLS_COMPRESSION_NULL)
186 compr_null_found = 1;
187 }
188 if (!compr_null_found) {
189 wpa_printf(MSG_INFO, "TLSv1: Client does not accept NULL "
190 "compression");
191 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
192 TLS_ALERT_ILLEGAL_PARAMETER);
193 return -1;
194 }
195
196 if (end - pos == 1) {
197 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected extra octet in the "
198 "end of ClientHello: 0x%02x", *pos);
199 goto decode_error;
200 }
201
202 if (end - pos >= 2) {
203 /* Extension client_hello_extension_list<0..2^16-1> */
204 ext_len = WPA_GET_BE16(pos);
205 pos += 2;
206
207 wpa_printf(MSG_DEBUG, "TLSv1: %u bytes of ClientHello "
208 "extensions", ext_len);
209 if (end - pos != ext_len) {
210 wpa_printf(MSG_DEBUG, "TLSv1: Invalid ClientHello "
211 "extension list length %u (expected %u)",
212 ext_len, (unsigned int) (end - pos));
213 goto decode_error;
214 }
215
216 /*
217 * struct {
218 * ExtensionType extension_type (0..65535)
219 * opaque extension_data<0..2^16-1>
220 * } Extension;
221 */
222
223 while (pos < end) {
224 if (end - pos < 2) {
225 wpa_printf(MSG_DEBUG, "TLSv1: Invalid "
226 "extension_type field");
227 goto decode_error;
228 }
229
230 ext_type = WPA_GET_BE16(pos);
231 pos += 2;
232
233 if (end - pos < 2) {
234 wpa_printf(MSG_DEBUG, "TLSv1: Invalid "
235 "extension_data length field");
236 goto decode_error;
237 }
238
239 ext_len = WPA_GET_BE16(pos);
240 pos += 2;
241
242 if (end - pos < ext_len) {
243 wpa_printf(MSG_DEBUG, "TLSv1: Invalid "
244 "extension_data field");
245 goto decode_error;
246 }
247
248 wpa_printf(MSG_DEBUG, "TLSv1: ClientHello Extension "
249 "type %u", ext_type);
250 wpa_hexdump(MSG_MSGDUMP, "TLSv1: ClientHello "
251 "Extension data", pos, ext_len);
252
253 if (ext_type == TLS_EXT_SESSION_TICKET) {
254 os_free(conn->session_ticket);
255 conn->session_ticket = os_malloc(ext_len);
256 if (conn->session_ticket) {
257 os_memcpy(conn->session_ticket, pos,
258 ext_len);
259 conn->session_ticket_len = ext_len;
260 }
261 }
262
263 pos += ext_len;
264 }
265 }
266
267 *in_len = end - in_data;
268
269 wpa_printf(MSG_DEBUG, "TLSv1: ClientHello OK - proceed to "
270 "ServerHello");
271 conn->state = SERVER_HELLO;
272
273 return 0;
274
275decode_error:
276 wpa_printf(MSG_DEBUG, "TLSv1: Failed to decode ClientHello");
277 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
278 TLS_ALERT_DECODE_ERROR);
279 return -1;
280}
281
282
283static int tls_process_certificate(struct tlsv1_server *conn, u8 ct,
284 const u8 *in_data, size_t *in_len)
285{
286 const u8 *pos, *end;
287 size_t left, len, list_len, cert_len, idx;
288 u8 type;
289 struct x509_certificate *chain = NULL, *last = NULL, *cert;
290 int reason;
291
292 if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
293 wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
294 "received content type 0x%x", ct);
295 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
296 TLS_ALERT_UNEXPECTED_MESSAGE);
297 return -1;
298 }
299
300 pos = in_data;
301 left = *in_len;
302
303 if (left < 4) {
304 wpa_printf(MSG_DEBUG, "TLSv1: Too short Certificate message "
305 "(len=%lu)", (unsigned long) left);
306 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
307 TLS_ALERT_DECODE_ERROR);
308 return -1;
309 }
310
311 type = *pos++;
312 len = WPA_GET_BE24(pos);
313 pos += 3;
314 left -= 4;
315
316 if (len > left) {
317 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected Certificate message "
318 "length (len=%lu != left=%lu)",
319 (unsigned long) len, (unsigned long) left);
320 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
321 TLS_ALERT_DECODE_ERROR);
322 return -1;
323 }
324
325 if (type == TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE) {
326 if (conn->verify_peer) {
327 wpa_printf(MSG_DEBUG, "TLSv1: Client did not include "
328 "Certificate");
329 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
330 TLS_ALERT_UNEXPECTED_MESSAGE);
331 return -1;
332 }
333
334 return tls_process_client_key_exchange(conn, ct, in_data,
335 in_len);
336 }
337 if (type != TLS_HANDSHAKE_TYPE_CERTIFICATE) {
338 wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
339 "message %d (expected Certificate/"
340 "ClientKeyExchange)", type);
341 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
342 TLS_ALERT_UNEXPECTED_MESSAGE);
343 return -1;
344 }
345
346 wpa_printf(MSG_DEBUG,
347 "TLSv1: Received Certificate (certificate_list len %lu)",
348 (unsigned long) len);
349
350 /*
351 * opaque ASN.1Cert<2^24-1>;
352 *
353 * struct {
354 * ASN.1Cert certificate_list<1..2^24-1>;
355 * } Certificate;
356 */
357
358 end = pos + len;
359
360 if (end - pos < 3) {
361 wpa_printf(MSG_DEBUG, "TLSv1: Too short Certificate "
362 "(left=%lu)", (unsigned long) left);
363 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
364 TLS_ALERT_DECODE_ERROR);
365 return -1;
366 }
367
368 list_len = WPA_GET_BE24(pos);
369 pos += 3;
370
371 if ((size_t) (end - pos) != list_len) {
372 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected certificate_list "
373 "length (len=%lu left=%lu)",
374 (unsigned long) list_len,
375 (unsigned long) (end - pos));
376 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
377 TLS_ALERT_DECODE_ERROR);
378 return -1;
379 }
380
381 idx = 0;
382 while (pos < end) {
383 if (end - pos < 3) {
384 wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse "
385 "certificate_list");
386 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
387 TLS_ALERT_DECODE_ERROR);
388 x509_certificate_chain_free(chain);
389 return -1;
390 }
391
392 cert_len = WPA_GET_BE24(pos);
393 pos += 3;
394
395 if ((size_t) (end - pos) < cert_len) {
396 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected certificate "
397 "length (len=%lu left=%lu)",
398 (unsigned long) cert_len,
399 (unsigned long) (end - pos));
400 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
401 TLS_ALERT_DECODE_ERROR);
402 x509_certificate_chain_free(chain);
403 return -1;
404 }
405
406 wpa_printf(MSG_DEBUG, "TLSv1: Certificate %lu (len %lu)",
407 (unsigned long) idx, (unsigned long) cert_len);
408
409 if (idx == 0) {
410 crypto_public_key_free(conn->client_rsa_key);
411 if (tls_parse_cert(pos, cert_len,
412 &conn->client_rsa_key)) {
413 wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse "
414 "the certificate");
415 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
416 TLS_ALERT_BAD_CERTIFICATE);
417 x509_certificate_chain_free(chain);
418 return -1;
419 }
420 }
421
422 cert = x509_certificate_parse(pos, cert_len);
423 if (cert == NULL) {
424 wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse "
425 "the certificate");
426 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
427 TLS_ALERT_BAD_CERTIFICATE);
428 x509_certificate_chain_free(chain);
429 return -1;
430 }
431
432 if (last == NULL)
433 chain = cert;
434 else
435 last->next = cert;
436 last = cert;
437
438 idx++;
439 pos += cert_len;
440 }
441
442 if (x509_certificate_chain_validate(conn->cred->trusted_certs, chain,
Dmitry Shmidtc55524a2011-07-07 11:18:38 -0700443 &reason, 0) < 0) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700444 int tls_reason;
445 wpa_printf(MSG_DEBUG, "TLSv1: Server certificate chain "
446 "validation failed (reason=%d)", reason);
447 switch (reason) {
448 case X509_VALIDATE_BAD_CERTIFICATE:
449 tls_reason = TLS_ALERT_BAD_CERTIFICATE;
450 break;
451 case X509_VALIDATE_UNSUPPORTED_CERTIFICATE:
452 tls_reason = TLS_ALERT_UNSUPPORTED_CERTIFICATE;
453 break;
454 case X509_VALIDATE_CERTIFICATE_REVOKED:
455 tls_reason = TLS_ALERT_CERTIFICATE_REVOKED;
456 break;
457 case X509_VALIDATE_CERTIFICATE_EXPIRED:
458 tls_reason = TLS_ALERT_CERTIFICATE_EXPIRED;
459 break;
460 case X509_VALIDATE_CERTIFICATE_UNKNOWN:
461 tls_reason = TLS_ALERT_CERTIFICATE_UNKNOWN;
462 break;
463 case X509_VALIDATE_UNKNOWN_CA:
464 tls_reason = TLS_ALERT_UNKNOWN_CA;
465 break;
466 default:
467 tls_reason = TLS_ALERT_BAD_CERTIFICATE;
468 break;
469 }
470 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, tls_reason);
471 x509_certificate_chain_free(chain);
472 return -1;
473 }
474
475 x509_certificate_chain_free(chain);
476
477 *in_len = end - in_data;
478
479 conn->state = CLIENT_KEY_EXCHANGE;
480
481 return 0;
482}
483
484
485static int tls_process_client_key_exchange_rsa(
486 struct tlsv1_server *conn, const u8 *pos, const u8 *end)
487{
488 u8 *out;
489 size_t outlen, outbuflen;
490 u16 encr_len;
491 int res;
492 int use_random = 0;
493
494 if (end - pos < 2) {
495 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
496 TLS_ALERT_DECODE_ERROR);
497 return -1;
498 }
499
500 encr_len = WPA_GET_BE16(pos);
501 pos += 2;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800502 if (pos + encr_len > end) {
503 wpa_printf(MSG_DEBUG, "TLSv1: Invalid ClientKeyExchange "
504 "format: encr_len=%u left=%u",
505 encr_len, (unsigned int) (end - pos));
506 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
507 TLS_ALERT_DECODE_ERROR);
508 return -1;
509 }
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700510
511 outbuflen = outlen = end - pos;
512 out = os_malloc(outlen >= TLS_PRE_MASTER_SECRET_LEN ?
513 outlen : TLS_PRE_MASTER_SECRET_LEN);
514 if (out == NULL) {
515 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
516 TLS_ALERT_INTERNAL_ERROR);
517 return -1;
518 }
519
520 /*
521 * struct {
522 * ProtocolVersion client_version;
523 * opaque random[46];
524 * } PreMasterSecret;
525 *
526 * struct {
527 * public-key-encrypted PreMasterSecret pre_master_secret;
528 * } EncryptedPreMasterSecret;
529 */
530
531 /*
532 * Note: To avoid Bleichenbacher attack, we do not report decryption or
533 * parsing errors from EncryptedPreMasterSecret processing to the
534 * client. Instead, a random pre-master secret is used to force the
535 * handshake to fail.
536 */
537
538 if (crypto_private_key_decrypt_pkcs1_v15(conn->cred->key,
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800539 pos, encr_len,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700540 out, &outlen) < 0) {
541 wpa_printf(MSG_DEBUG, "TLSv1: Failed to decrypt "
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800542 "PreMasterSecret (encr_len=%u outlen=%lu)",
543 encr_len, (unsigned long) outlen);
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700544 use_random = 1;
545 }
546
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800547 if (!use_random && outlen != TLS_PRE_MASTER_SECRET_LEN) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700548 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected PreMasterSecret "
549 "length %lu", (unsigned long) outlen);
550 use_random = 1;
551 }
552
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800553 if (!use_random && WPA_GET_BE16(out) != conn->client_version) {
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700554 wpa_printf(MSG_DEBUG, "TLSv1: Client version in "
555 "ClientKeyExchange does not match with version in "
556 "ClientHello");
557 use_random = 1;
558 }
559
560 if (use_random) {
561 wpa_printf(MSG_DEBUG, "TLSv1: Using random premaster secret "
562 "to avoid revealing information about private key");
563 outlen = TLS_PRE_MASTER_SECRET_LEN;
564 if (os_get_random(out, outlen)) {
565 wpa_printf(MSG_DEBUG, "TLSv1: Failed to get random "
566 "data");
567 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
568 TLS_ALERT_INTERNAL_ERROR);
569 os_free(out);
570 return -1;
571 }
572 }
573
574 res = tlsv1_server_derive_keys(conn, out, outlen);
575
576 /* Clear the pre-master secret since it is not needed anymore */
577 os_memset(out, 0, outbuflen);
578 os_free(out);
579
580 if (res) {
581 wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive keys");
582 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
583 TLS_ALERT_INTERNAL_ERROR);
584 return -1;
585 }
586
587 return 0;
588}
589
590
591static int tls_process_client_key_exchange_dh_anon(
592 struct tlsv1_server *conn, const u8 *pos, const u8 *end)
593{
594 const u8 *dh_yc;
595 u16 dh_yc_len;
596 u8 *shared;
597 size_t shared_len;
598 int res;
599
600 /*
601 * struct {
602 * select (PublicValueEncoding) {
603 * case implicit: struct { };
604 * case explicit: opaque dh_Yc<1..2^16-1>;
605 * } dh_public;
606 * } ClientDiffieHellmanPublic;
607 */
608
609 wpa_hexdump(MSG_MSGDUMP, "TLSv1: ClientDiffieHellmanPublic",
610 pos, end - pos);
611
612 if (end == pos) {
613 wpa_printf(MSG_DEBUG, "TLSv1: Implicit public value encoding "
614 "not supported");
615 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
616 TLS_ALERT_INTERNAL_ERROR);
617 return -1;
618 }
619
620 if (end - pos < 3) {
621 wpa_printf(MSG_DEBUG, "TLSv1: Invalid client public value "
622 "length");
623 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
624 TLS_ALERT_DECODE_ERROR);
625 return -1;
626 }
627
628 dh_yc_len = WPA_GET_BE16(pos);
629 dh_yc = pos + 2;
630
631 if (dh_yc + dh_yc_len > end) {
632 wpa_printf(MSG_DEBUG, "TLSv1: Client public value overflow "
633 "(length %d)", dh_yc_len);
634 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
635 TLS_ALERT_DECODE_ERROR);
636 return -1;
637 }
638
639 wpa_hexdump(MSG_DEBUG, "TLSv1: DH Yc (client's public value)",
640 dh_yc, dh_yc_len);
641
642 if (conn->cred == NULL || conn->cred->dh_p == NULL ||
643 conn->dh_secret == NULL) {
644 wpa_printf(MSG_DEBUG, "TLSv1: No DH parameters available");
645 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
646 TLS_ALERT_INTERNAL_ERROR);
647 return -1;
648 }
649
650 shared_len = conn->cred->dh_p_len;
651 shared = os_malloc(shared_len);
652 if (shared == NULL) {
653 wpa_printf(MSG_DEBUG, "TLSv1: Could not allocate memory for "
654 "DH");
655 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
656 TLS_ALERT_INTERNAL_ERROR);
657 return -1;
658 }
659
660 /* shared = Yc^secret mod p */
661 if (crypto_mod_exp(dh_yc, dh_yc_len, conn->dh_secret,
662 conn->dh_secret_len,
663 conn->cred->dh_p, conn->cred->dh_p_len,
664 shared, &shared_len)) {
665 os_free(shared);
666 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
667 TLS_ALERT_INTERNAL_ERROR);
668 return -1;
669 }
670 wpa_hexdump_key(MSG_DEBUG, "TLSv1: Shared secret from DH key exchange",
671 shared, shared_len);
672
673 os_memset(conn->dh_secret, 0, conn->dh_secret_len);
674 os_free(conn->dh_secret);
675 conn->dh_secret = NULL;
676
677 res = tlsv1_server_derive_keys(conn, shared, shared_len);
678
679 /* Clear the pre-master secret since it is not needed anymore */
680 os_memset(shared, 0, shared_len);
681 os_free(shared);
682
683 if (res) {
684 wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive keys");
685 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
686 TLS_ALERT_INTERNAL_ERROR);
687 return -1;
688 }
689
690 return 0;
691}
692
693
694static int tls_process_client_key_exchange(struct tlsv1_server *conn, u8 ct,
695 const u8 *in_data, size_t *in_len)
696{
697 const u8 *pos, *end;
698 size_t left, len;
699 u8 type;
700 tls_key_exchange keyx;
701 const struct tls_cipher_suite *suite;
702
703 if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
704 wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
705 "received content type 0x%x", ct);
706 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
707 TLS_ALERT_UNEXPECTED_MESSAGE);
708 return -1;
709 }
710
711 pos = in_data;
712 left = *in_len;
713
714 if (left < 4) {
715 wpa_printf(MSG_DEBUG, "TLSv1: Too short ClientKeyExchange "
716 "(Left=%lu)", (unsigned long) left);
717 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
718 TLS_ALERT_DECODE_ERROR);
719 return -1;
720 }
721
722 type = *pos++;
723 len = WPA_GET_BE24(pos);
724 pos += 3;
725 left -= 4;
726
727 if (len > left) {
728 wpa_printf(MSG_DEBUG, "TLSv1: Mismatch in ClientKeyExchange "
729 "length (len=%lu != left=%lu)",
730 (unsigned long) len, (unsigned long) left);
731 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
732 TLS_ALERT_DECODE_ERROR);
733 return -1;
734 }
735
736 end = pos + len;
737
738 if (type != TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE) {
739 wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
740 "message %d (expected ClientKeyExchange)", type);
741 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
742 TLS_ALERT_UNEXPECTED_MESSAGE);
743 return -1;
744 }
745
746 wpa_printf(MSG_DEBUG, "TLSv1: Received ClientKeyExchange");
747
748 wpa_hexdump(MSG_DEBUG, "TLSv1: ClientKeyExchange", pos, len);
749
750 suite = tls_get_cipher_suite(conn->rl.cipher_suite);
751 if (suite == NULL)
752 keyx = TLS_KEY_X_NULL;
753 else
754 keyx = suite->key_exchange;
755
756 if (keyx == TLS_KEY_X_DH_anon &&
757 tls_process_client_key_exchange_dh_anon(conn, pos, end) < 0)
758 return -1;
759
760 if (keyx != TLS_KEY_X_DH_anon &&
761 tls_process_client_key_exchange_rsa(conn, pos, end) < 0)
762 return -1;
763
764 *in_len = end - in_data;
765
766 conn->state = CERTIFICATE_VERIFY;
767
768 return 0;
769}
770
771
772static int tls_process_certificate_verify(struct tlsv1_server *conn, u8 ct,
773 const u8 *in_data, size_t *in_len)
774{
775 const u8 *pos, *end;
776 size_t left, len;
777 u8 type;
778 size_t hlen, buflen;
779 u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN], *hpos, *buf;
780 enum { SIGN_ALG_RSA, SIGN_ALG_DSA } alg = SIGN_ALG_RSA;
781 u16 slen;
782
783 if (ct == TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC) {
784 if (conn->verify_peer) {
785 wpa_printf(MSG_DEBUG, "TLSv1: Client did not include "
786 "CertificateVerify");
787 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
788 TLS_ALERT_UNEXPECTED_MESSAGE);
789 return -1;
790 }
791
792 return tls_process_change_cipher_spec(conn, ct, in_data,
793 in_len);
794 }
795
796 if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
797 wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
798 "received content type 0x%x", ct);
799 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
800 TLS_ALERT_UNEXPECTED_MESSAGE);
801 return -1;
802 }
803
804 pos = in_data;
805 left = *in_len;
806
807 if (left < 4) {
808 wpa_printf(MSG_DEBUG, "TLSv1: Too short CertificateVerify "
809 "message (len=%lu)", (unsigned long) left);
810 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
811 TLS_ALERT_DECODE_ERROR);
812 return -1;
813 }
814
815 type = *pos++;
816 len = WPA_GET_BE24(pos);
817 pos += 3;
818 left -= 4;
819
820 if (len > left) {
821 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected CertificateVerify "
822 "message length (len=%lu != left=%lu)",
823 (unsigned long) len, (unsigned long) left);
824 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
825 TLS_ALERT_DECODE_ERROR);
826 return -1;
827 }
828
829 end = pos + len;
830
831 if (type != TLS_HANDSHAKE_TYPE_CERTIFICATE_VERIFY) {
832 wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
833 "message %d (expected CertificateVerify)", type);
834 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
835 TLS_ALERT_UNEXPECTED_MESSAGE);
836 return -1;
837 }
838
839 wpa_printf(MSG_DEBUG, "TLSv1: Received CertificateVerify");
840
841 /*
842 * struct {
843 * Signature signature;
844 * } CertificateVerify;
845 */
846
847 hpos = hash;
848
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800849#ifdef CONFIG_TLSV12
850 if (conn->rl.tls_version == TLS_VERSION_1_2) {
851 /*
852 * RFC 5246, 4.7:
853 * TLS v1.2 adds explicit indication of the used signature and
854 * hash algorithms.
855 *
856 * struct {
857 * HashAlgorithm hash;
858 * SignatureAlgorithm signature;
859 * } SignatureAndHashAlgorithm;
860 */
861 if (end - pos < 2) {
862 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
863 TLS_ALERT_DECODE_ERROR);
864 return -1;
865 }
866 if (pos[0] != TLS_HASH_ALG_SHA256 ||
867 pos[1] != TLS_SIGN_ALG_RSA) {
868 wpa_printf(MSG_DEBUG, "TLSv1.2: Unsupported hash(%u)/"
869 "signature(%u) algorithm",
870 pos[0], pos[1]);
871 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
872 TLS_ALERT_INTERNAL_ERROR);
873 return -1;
874 }
875 pos += 2;
876
877 hlen = SHA256_MAC_LEN;
878 if (conn->verify.sha256_cert == NULL ||
879 crypto_hash_finish(conn->verify.sha256_cert, hpos, &hlen) <
880 0) {
881 conn->verify.sha256_cert = NULL;
882 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
883 TLS_ALERT_INTERNAL_ERROR);
884 return -1;
885 }
886 conn->verify.sha256_cert = NULL;
887 } else {
888#endif /* CONFIG_TLSV12 */
889
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700890 if (alg == SIGN_ALG_RSA) {
891 hlen = MD5_MAC_LEN;
892 if (conn->verify.md5_cert == NULL ||
893 crypto_hash_finish(conn->verify.md5_cert, hpos, &hlen) < 0)
894 {
895 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
896 TLS_ALERT_INTERNAL_ERROR);
897 conn->verify.md5_cert = NULL;
898 crypto_hash_finish(conn->verify.sha1_cert, NULL, NULL);
899 conn->verify.sha1_cert = NULL;
900 return -1;
901 }
902 hpos += MD5_MAC_LEN;
903 } else
904 crypto_hash_finish(conn->verify.md5_cert, NULL, NULL);
905
906 conn->verify.md5_cert = NULL;
907 hlen = SHA1_MAC_LEN;
908 if (conn->verify.sha1_cert == NULL ||
909 crypto_hash_finish(conn->verify.sha1_cert, hpos, &hlen) < 0) {
910 conn->verify.sha1_cert = NULL;
911 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
912 TLS_ALERT_INTERNAL_ERROR);
913 return -1;
914 }
915 conn->verify.sha1_cert = NULL;
916
917 if (alg == SIGN_ALG_RSA)
918 hlen += MD5_MAC_LEN;
919
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800920#ifdef CONFIG_TLSV12
921 }
922#endif /* CONFIG_TLSV12 */
923
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700924 wpa_hexdump(MSG_MSGDUMP, "TLSv1: CertificateVerify hash", hash, hlen);
925
926 if (end - pos < 2) {
927 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
928 TLS_ALERT_DECODE_ERROR);
929 return -1;
930 }
931 slen = WPA_GET_BE16(pos);
932 pos += 2;
933 if (end - pos < slen) {
934 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
935 TLS_ALERT_DECODE_ERROR);
936 return -1;
937 }
938
939 wpa_hexdump(MSG_MSGDUMP, "TLSv1: Signature", pos, end - pos);
940 if (conn->client_rsa_key == NULL) {
941 wpa_printf(MSG_DEBUG, "TLSv1: No client public key to verify "
942 "signature");
943 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
944 TLS_ALERT_INTERNAL_ERROR);
945 return -1;
946 }
947
948 buflen = end - pos;
949 buf = os_malloc(end - pos);
950 if (crypto_public_key_decrypt_pkcs1(conn->client_rsa_key,
951 pos, end - pos, buf, &buflen) < 0)
952 {
953 wpa_printf(MSG_DEBUG, "TLSv1: Failed to decrypt signature");
954 os_free(buf);
955 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
956 TLS_ALERT_DECRYPT_ERROR);
957 return -1;
958 }
959
960 wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: Decrypted Signature",
961 buf, buflen);
962
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -0800963#ifdef CONFIG_TLSV12
964 if (conn->rl.tls_version >= TLS_VERSION_1_2) {
965 /*
966 * RFC 3447, A.2.4 RSASSA-PKCS1-v1_5
967 *
968 * DigestInfo ::= SEQUENCE {
969 * digestAlgorithm DigestAlgorithm,
970 * digest OCTET STRING
971 * }
972 *
973 * SHA-256 OID: sha256WithRSAEncryption ::= {pkcs-1 11}
974 *
975 * DER encoded DigestInfo for SHA256 per RFC 3447:
976 * 30 31 30 0d 06 09 60 86 48 01 65 03 04 02 01 05 00 04 20 ||
977 * H
978 */
979 if (buflen >= 19 + 32 &&
980 os_memcmp(buf, "\x30\x31\x30\x0d\x06\x09\x60\x86\x48\x01"
981 "\x65\x03\x04\x02\x01\x05\x00\x04\x20", 19) == 0)
982 {
983 wpa_printf(MSG_DEBUG, "TLSv1.2: DigestAlgorithn = "
984 "SHA-256");
985 os_memmove(buf, buf + 19, buflen - 19);
986 buflen -= 19;
987 } else {
988 wpa_printf(MSG_DEBUG, "TLSv1.2: Unrecognized "
989 "DigestInfo");
990 os_free(buf);
991 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
992 TLS_ALERT_DECRYPT_ERROR);
993 return -1;
994 }
995 }
996#endif /* CONFIG_TLSV12 */
997
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -0700998 if (buflen != hlen || os_memcmp(buf, hash, buflen) != 0) {
999 wpa_printf(MSG_DEBUG, "TLSv1: Invalid Signature in "
1000 "CertificateVerify - did not match with calculated "
1001 "hash");
1002 os_free(buf);
1003 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
1004 TLS_ALERT_DECRYPT_ERROR);
1005 return -1;
1006 }
1007
1008 os_free(buf);
1009
1010 *in_len = end - in_data;
1011
1012 conn->state = CHANGE_CIPHER_SPEC;
1013
1014 return 0;
1015}
1016
1017
1018static int tls_process_change_cipher_spec(struct tlsv1_server *conn,
1019 u8 ct, const u8 *in_data,
1020 size_t *in_len)
1021{
1022 const u8 *pos;
1023 size_t left;
1024
1025 if (ct != TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC) {
1026 wpa_printf(MSG_DEBUG, "TLSv1: Expected ChangeCipherSpec; "
1027 "received content type 0x%x", ct);
1028 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
1029 TLS_ALERT_UNEXPECTED_MESSAGE);
1030 return -1;
1031 }
1032
1033 pos = in_data;
1034 left = *in_len;
1035
1036 if (left < 1) {
1037 wpa_printf(MSG_DEBUG, "TLSv1: Too short ChangeCipherSpec");
1038 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
1039 TLS_ALERT_DECODE_ERROR);
1040 return -1;
1041 }
1042
1043 if (*pos != TLS_CHANGE_CIPHER_SPEC) {
1044 wpa_printf(MSG_DEBUG, "TLSv1: Expected ChangeCipherSpec; "
1045 "received data 0x%x", *pos);
1046 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
1047 TLS_ALERT_UNEXPECTED_MESSAGE);
1048 return -1;
1049 }
1050
1051 wpa_printf(MSG_DEBUG, "TLSv1: Received ChangeCipherSpec");
1052 if (tlsv1_record_change_read_cipher(&conn->rl) < 0) {
1053 wpa_printf(MSG_DEBUG, "TLSv1: Failed to change read cipher "
1054 "for record layer");
1055 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
1056 TLS_ALERT_INTERNAL_ERROR);
1057 return -1;
1058 }
1059
1060 *in_len = pos + 1 - in_data;
1061
1062 conn->state = CLIENT_FINISHED;
1063
1064 return 0;
1065}
1066
1067
1068static int tls_process_client_finished(struct tlsv1_server *conn, u8 ct,
1069 const u8 *in_data, size_t *in_len)
1070{
1071 const u8 *pos, *end;
1072 size_t left, len, hlen;
1073 u8 verify_data[TLS_VERIFY_DATA_LEN];
1074 u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN];
1075
1076 if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
1077 wpa_printf(MSG_DEBUG, "TLSv1: Expected Finished; "
1078 "received content type 0x%x", ct);
1079 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
1080 TLS_ALERT_UNEXPECTED_MESSAGE);
1081 return -1;
1082 }
1083
1084 pos = in_data;
1085 left = *in_len;
1086
1087 if (left < 4) {
1088 wpa_printf(MSG_DEBUG, "TLSv1: Too short record (left=%lu) for "
1089 "Finished",
1090 (unsigned long) left);
1091 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
1092 TLS_ALERT_DECODE_ERROR);
1093 return -1;
1094 }
1095
1096 if (pos[0] != TLS_HANDSHAKE_TYPE_FINISHED) {
1097 wpa_printf(MSG_DEBUG, "TLSv1: Expected Finished; received "
1098 "type 0x%x", pos[0]);
1099 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
1100 TLS_ALERT_UNEXPECTED_MESSAGE);
1101 return -1;
1102 }
1103
1104 len = WPA_GET_BE24(pos + 1);
1105
1106 pos += 4;
1107 left -= 4;
1108
1109 if (len > left) {
1110 wpa_printf(MSG_DEBUG, "TLSv1: Too short buffer for Finished "
1111 "(len=%lu > left=%lu)",
1112 (unsigned long) len, (unsigned long) left);
1113 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
1114 TLS_ALERT_DECODE_ERROR);
1115 return -1;
1116 }
1117 end = pos + len;
1118 if (len != TLS_VERIFY_DATA_LEN) {
1119 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected verify_data length "
1120 "in Finished: %lu (expected %d)",
1121 (unsigned long) len, TLS_VERIFY_DATA_LEN);
1122 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
1123 TLS_ALERT_DECODE_ERROR);
1124 return -1;
1125 }
1126 wpa_hexdump(MSG_MSGDUMP, "TLSv1: verify_data in Finished",
1127 pos, TLS_VERIFY_DATA_LEN);
1128
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001129#ifdef CONFIG_TLSV12
1130 if (conn->rl.tls_version >= TLS_VERSION_1_2) {
1131 hlen = SHA256_MAC_LEN;
1132 if (conn->verify.sha256_client == NULL ||
1133 crypto_hash_finish(conn->verify.sha256_client, hash, &hlen)
1134 < 0) {
1135 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
1136 TLS_ALERT_INTERNAL_ERROR);
1137 conn->verify.sha256_client = NULL;
1138 return -1;
1139 }
1140 conn->verify.sha256_client = NULL;
1141 } else {
1142#endif /* CONFIG_TLSV12 */
1143
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001144 hlen = MD5_MAC_LEN;
1145 if (conn->verify.md5_client == NULL ||
1146 crypto_hash_finish(conn->verify.md5_client, hash, &hlen) < 0) {
1147 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
1148 TLS_ALERT_INTERNAL_ERROR);
1149 conn->verify.md5_client = NULL;
1150 crypto_hash_finish(conn->verify.sha1_client, NULL, NULL);
1151 conn->verify.sha1_client = NULL;
1152 return -1;
1153 }
1154 conn->verify.md5_client = NULL;
1155 hlen = SHA1_MAC_LEN;
1156 if (conn->verify.sha1_client == NULL ||
1157 crypto_hash_finish(conn->verify.sha1_client, hash + MD5_MAC_LEN,
1158 &hlen) < 0) {
1159 conn->verify.sha1_client = NULL;
1160 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
1161 TLS_ALERT_INTERNAL_ERROR);
1162 return -1;
1163 }
1164 conn->verify.sha1_client = NULL;
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001165 hlen = MD5_MAC_LEN + SHA1_MAC_LEN;
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001166
Dmitry Shmidt1f69aa52012-01-24 16:10:04 -08001167#ifdef CONFIG_TLSV12
1168 }
1169#endif /* CONFIG_TLSV12 */
1170
1171 if (tls_prf(conn->rl.tls_version,
1172 conn->master_secret, TLS_MASTER_SECRET_LEN,
1173 "client finished", hash, hlen,
Dmitry Shmidt8d520ff2011-05-09 14:06:53 -07001174 verify_data, TLS_VERIFY_DATA_LEN)) {
1175 wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive verify_data");
1176 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
1177 TLS_ALERT_DECRYPT_ERROR);
1178 return -1;
1179 }
1180 wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (client)",
1181 verify_data, TLS_VERIFY_DATA_LEN);
1182
1183 if (os_memcmp(pos, verify_data, TLS_VERIFY_DATA_LEN) != 0) {
1184 wpa_printf(MSG_INFO, "TLSv1: Mismatch in verify_data");
1185 return -1;
1186 }
1187
1188 wpa_printf(MSG_DEBUG, "TLSv1: Received Finished");
1189
1190 *in_len = end - in_data;
1191
1192 if (conn->use_session_ticket) {
1193 /* Abbreviated handshake using session ticket; RFC 4507 */
1194 wpa_printf(MSG_DEBUG, "TLSv1: Abbreviated handshake completed "
1195 "successfully");
1196 conn->state = ESTABLISHED;
1197 } else {
1198 /* Full handshake */
1199 conn->state = SERVER_CHANGE_CIPHER_SPEC;
1200 }
1201
1202 return 0;
1203}
1204
1205
1206int tlsv1_server_process_handshake(struct tlsv1_server *conn, u8 ct,
1207 const u8 *buf, size_t *len)
1208{
1209 if (ct == TLS_CONTENT_TYPE_ALERT) {
1210 if (*len < 2) {
1211 wpa_printf(MSG_DEBUG, "TLSv1: Alert underflow");
1212 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
1213 TLS_ALERT_DECODE_ERROR);
1214 return -1;
1215 }
1216 wpa_printf(MSG_DEBUG, "TLSv1: Received alert %d:%d",
1217 buf[0], buf[1]);
1218 *len = 2;
1219 conn->state = FAILED;
1220 return -1;
1221 }
1222
1223 switch (conn->state) {
1224 case CLIENT_HELLO:
1225 if (tls_process_client_hello(conn, ct, buf, len))
1226 return -1;
1227 break;
1228 case CLIENT_CERTIFICATE:
1229 if (tls_process_certificate(conn, ct, buf, len))
1230 return -1;
1231 break;
1232 case CLIENT_KEY_EXCHANGE:
1233 if (tls_process_client_key_exchange(conn, ct, buf, len))
1234 return -1;
1235 break;
1236 case CERTIFICATE_VERIFY:
1237 if (tls_process_certificate_verify(conn, ct, buf, len))
1238 return -1;
1239 break;
1240 case CHANGE_CIPHER_SPEC:
1241 if (tls_process_change_cipher_spec(conn, ct, buf, len))
1242 return -1;
1243 break;
1244 case CLIENT_FINISHED:
1245 if (tls_process_client_finished(conn, ct, buf, len))
1246 return -1;
1247 break;
1248 default:
1249 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected state %d "
1250 "while processing received message",
1251 conn->state);
1252 return -1;
1253 }
1254
1255 if (ct == TLS_CONTENT_TYPE_HANDSHAKE)
1256 tls_verify_hash_add(&conn->verify, buf, *len);
1257
1258 return 0;
1259}