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