00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "includes.h"
00016
00017 #include "common.h"
00018 #include "crypto/md5.h"
00019 #include "crypto/sha1.h"
00020 #include "crypto/tls.h"
00021 #include "x509v3.h"
00022 #include "tlsv1_common.h"
00023 #include "tlsv1_record.h"
00024 #include "tlsv1_client.h"
00025 #include "tlsv1_client_i.h"
00026
00027 static int tls_process_server_key_exchange(struct tlsv1_client *conn, u8 ct,
00028 const u8 *in_data, size_t *in_len);
00029 static int tls_process_certificate_request(struct tlsv1_client *conn, u8 ct,
00030 const u8 *in_data, size_t *in_len);
00031 static int tls_process_server_hello_done(struct tlsv1_client *conn, u8 ct,
00032 const u8 *in_data, size_t *in_len);
00033
00034
00035 static int tls_process_server_hello(struct tlsv1_client *conn, u8 ct,
00036 const u8 *in_data, size_t *in_len)
00037 {
00038 const u8 *pos, *end;
00039 size_t left, len, i;
00040 u16 cipher_suite;
00041
00042 if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
00043 wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
00044 "received content type 0x%x", ct);
00045 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00046 TLS_ALERT_UNEXPECTED_MESSAGE);
00047 return -1;
00048 }
00049
00050 pos = in_data;
00051 left = *in_len;
00052
00053 if (left < 4)
00054 goto decode_error;
00055
00056
00057 if (*pos != TLS_HANDSHAKE_TYPE_SERVER_HELLO) {
00058 wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
00059 "message %d (expected ServerHello)", *pos);
00060 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00061 TLS_ALERT_UNEXPECTED_MESSAGE);
00062 return -1;
00063 }
00064 wpa_printf(MSG_DEBUG, "TLSv1: Received ServerHello");
00065 pos++;
00066
00067 len = WPA_GET_BE24(pos);
00068 pos += 3;
00069 left -= 4;
00070
00071 if (len > left)
00072 goto decode_error;
00073
00074
00075
00076 wpa_hexdump(MSG_MSGDUMP, "TLSv1: ServerHello", pos, len);
00077 end = pos + len;
00078
00079
00080 if (end - pos < 2)
00081 goto decode_error;
00082 if (WPA_GET_BE16(pos) != TLS_VERSION) {
00083 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected protocol version in "
00084 "ServerHello");
00085 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00086 TLS_ALERT_PROTOCOL_VERSION);
00087 return -1;
00088 }
00089 pos += 2;
00090
00091
00092 if (end - pos < TLS_RANDOM_LEN)
00093 goto decode_error;
00094
00095 os_memcpy(conn->server_random, pos, TLS_RANDOM_LEN);
00096 pos += TLS_RANDOM_LEN;
00097 wpa_hexdump(MSG_MSGDUMP, "TLSv1: server_random",
00098 conn->server_random, TLS_RANDOM_LEN);
00099
00100
00101 if (end - pos < 1)
00102 goto decode_error;
00103 if (end - pos < 1 + *pos || *pos > TLS_SESSION_ID_MAX_LEN)
00104 goto decode_error;
00105 if (conn->session_id_len && conn->session_id_len == *pos &&
00106 os_memcmp(conn->session_id, pos + 1, conn->session_id_len) == 0) {
00107 pos += 1 + conn->session_id_len;
00108 wpa_printf(MSG_DEBUG, "TLSv1: Resuming old session");
00109 conn->session_resumed = 1;
00110 } else {
00111 conn->session_id_len = *pos;
00112 pos++;
00113 os_memcpy(conn->session_id, pos, conn->session_id_len);
00114 pos += conn->session_id_len;
00115 }
00116 wpa_hexdump(MSG_MSGDUMP, "TLSv1: session_id",
00117 conn->session_id, conn->session_id_len);
00118
00119
00120 if (end - pos < 2)
00121 goto decode_error;
00122 cipher_suite = WPA_GET_BE16(pos);
00123 pos += 2;
00124 for (i = 0; i < conn->num_cipher_suites; i++) {
00125 if (cipher_suite == conn->cipher_suites[i])
00126 break;
00127 }
00128 if (i == conn->num_cipher_suites) {
00129 wpa_printf(MSG_INFO, "TLSv1: Server selected unexpected "
00130 "cipher suite 0x%04x", cipher_suite);
00131 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00132 TLS_ALERT_ILLEGAL_PARAMETER);
00133 return -1;
00134 }
00135
00136 if (conn->session_resumed && cipher_suite != conn->prev_cipher_suite) {
00137 wpa_printf(MSG_DEBUG, "TLSv1: Server selected a different "
00138 "cipher suite for a resumed connection (0x%04x != "
00139 "0x%04x)", cipher_suite, conn->prev_cipher_suite);
00140 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00141 TLS_ALERT_ILLEGAL_PARAMETER);
00142 return -1;
00143 }
00144
00145 if (tlsv1_record_set_cipher_suite(&conn->rl, cipher_suite) < 0) {
00146 wpa_printf(MSG_DEBUG, "TLSv1: Failed to set CipherSuite for "
00147 "record layer");
00148 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00149 TLS_ALERT_INTERNAL_ERROR);
00150 return -1;
00151 }
00152
00153 conn->prev_cipher_suite = cipher_suite;
00154
00155
00156 if (end - pos < 1)
00157 goto decode_error;
00158 if (*pos != TLS_COMPRESSION_NULL) {
00159 wpa_printf(MSG_INFO, "TLSv1: Server selected unexpected "
00160 "compression 0x%02x", *pos);
00161 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00162 TLS_ALERT_ILLEGAL_PARAMETER);
00163 return -1;
00164 }
00165 pos++;
00166
00167 if (end != pos) {
00168
00169 wpa_hexdump(MSG_DEBUG, "TLSv1: Unexpected extra data in the "
00170 "end of ServerHello", pos, end - pos);
00171 goto decode_error;
00172 }
00173
00174 if (conn->session_ticket_included && conn->session_ticket_cb) {
00175
00176
00177 int res = conn->session_ticket_cb(
00178 conn->session_ticket_cb_ctx, NULL, 0,
00179 conn->client_random, conn->server_random,
00180 conn->master_secret);
00181 if (res < 0) {
00182 wpa_printf(MSG_DEBUG, "TLSv1: SessionTicket callback "
00183 "indicated failure");
00184 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00185 TLS_ALERT_HANDSHAKE_FAILURE);
00186 return -1;
00187 }
00188 conn->use_session_ticket = !!res;
00189 }
00190
00191 if ((conn->session_resumed || conn->use_session_ticket) &&
00192 tls_derive_keys(conn, NULL, 0)) {
00193 wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive keys");
00194 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00195 TLS_ALERT_INTERNAL_ERROR);
00196 return -1;
00197 }
00198
00199 *in_len = end - in_data;
00200
00201 conn->state = (conn->session_resumed || conn->use_session_ticket) ?
00202 SERVER_CHANGE_CIPHER_SPEC : SERVER_CERTIFICATE;
00203
00204 return 0;
00205
00206 decode_error:
00207 wpa_printf(MSG_DEBUG, "TLSv1: Failed to decode ServerHello");
00208 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
00209 return -1;
00210 }
00211
00212
00213 static int tls_process_certificate(struct tlsv1_client *conn, u8 ct,
00214 const u8 *in_data, size_t *in_len)
00215 {
00216 const u8 *pos, *end;
00217 size_t left, len, list_len, cert_len, idx;
00218 u8 type;
00219 struct x509_certificate *chain = NULL, *last = NULL, *cert;
00220 int reason;
00221
00222 if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
00223 wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
00224 "received content type 0x%x", ct);
00225 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00226 TLS_ALERT_UNEXPECTED_MESSAGE);
00227 return -1;
00228 }
00229
00230 pos = in_data;
00231 left = *in_len;
00232
00233 if (left < 4) {
00234 wpa_printf(MSG_DEBUG, "TLSv1: Too short Certificate message "
00235 "(len=%lu)", (unsigned long) left);
00236 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
00237 return -1;
00238 }
00239
00240 type = *pos++;
00241 len = WPA_GET_BE24(pos);
00242 pos += 3;
00243 left -= 4;
00244
00245 if (len > left) {
00246 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected Certificate message "
00247 "length (len=%lu != left=%lu)",
00248 (unsigned long) len, (unsigned long) left);
00249 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
00250 return -1;
00251 }
00252
00253 if (type == TLS_HANDSHAKE_TYPE_SERVER_KEY_EXCHANGE)
00254 return tls_process_server_key_exchange(conn, ct, in_data,
00255 in_len);
00256 if (type == TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST)
00257 return tls_process_certificate_request(conn, ct, in_data,
00258 in_len);
00259 if (type == TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE)
00260 return tls_process_server_hello_done(conn, ct, in_data,
00261 in_len);
00262 if (type != TLS_HANDSHAKE_TYPE_CERTIFICATE) {
00263 wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
00264 "message %d (expected Certificate/"
00265 "ServerKeyExchange/CertificateRequest/"
00266 "ServerHelloDone)", type);
00267 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00268 TLS_ALERT_UNEXPECTED_MESSAGE);
00269 return -1;
00270 }
00271
00272 wpa_printf(MSG_DEBUG,
00273 "TLSv1: Received Certificate (certificate_list len %lu)",
00274 (unsigned long) len);
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 end = pos + len;
00285
00286 if (end - pos < 3) {
00287 wpa_printf(MSG_DEBUG, "TLSv1: Too short Certificate "
00288 "(left=%lu)", (unsigned long) left);
00289 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
00290 return -1;
00291 }
00292
00293 list_len = WPA_GET_BE24(pos);
00294 pos += 3;
00295
00296 if ((size_t) (end - pos) != list_len) {
00297 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected certificate_list "
00298 "length (len=%lu left=%lu)",
00299 (unsigned long) list_len,
00300 (unsigned long) (end - pos));
00301 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
00302 return -1;
00303 }
00304
00305 idx = 0;
00306 while (pos < end) {
00307 if (end - pos < 3) {
00308 wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse "
00309 "certificate_list");
00310 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00311 TLS_ALERT_DECODE_ERROR);
00312 x509_certificate_chain_free(chain);
00313 return -1;
00314 }
00315
00316 cert_len = WPA_GET_BE24(pos);
00317 pos += 3;
00318
00319 if ((size_t) (end - pos) < cert_len) {
00320 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected certificate "
00321 "length (len=%lu left=%lu)",
00322 (unsigned long) cert_len,
00323 (unsigned long) (end - pos));
00324 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00325 TLS_ALERT_DECODE_ERROR);
00326 x509_certificate_chain_free(chain);
00327 return -1;
00328 }
00329
00330 wpa_printf(MSG_DEBUG, "TLSv1: Certificate %lu (len %lu)",
00331 (unsigned long) idx, (unsigned long) cert_len);
00332
00333 if (idx == 0) {
00334 crypto_public_key_free(conn->server_rsa_key);
00335 if (tls_parse_cert(pos, cert_len,
00336 &conn->server_rsa_key)) {
00337 wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse "
00338 "the certificate");
00339 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00340 TLS_ALERT_BAD_CERTIFICATE);
00341 x509_certificate_chain_free(chain);
00342 return -1;
00343 }
00344 }
00345
00346 cert = x509_certificate_parse(pos, cert_len);
00347 if (cert == NULL) {
00348 wpa_printf(MSG_DEBUG, "TLSv1: Failed to parse "
00349 "the certificate");
00350 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00351 TLS_ALERT_BAD_CERTIFICATE);
00352 x509_certificate_chain_free(chain);
00353 return -1;
00354 }
00355
00356 if (last == NULL)
00357 chain = cert;
00358 else
00359 last->next = cert;
00360 last = cert;
00361
00362 idx++;
00363 pos += cert_len;
00364 }
00365
00366 if (conn->cred &&
00367 x509_certificate_chain_validate(conn->cred->trusted_certs, chain,
00368 &reason) < 0) {
00369 int tls_reason;
00370 wpa_printf(MSG_DEBUG, "TLSv1: Server certificate chain "
00371 "validation failed (reason=%d)", reason);
00372 switch (reason) {
00373 case X509_VALIDATE_BAD_CERTIFICATE:
00374 tls_reason = TLS_ALERT_BAD_CERTIFICATE;
00375 break;
00376 case X509_VALIDATE_UNSUPPORTED_CERTIFICATE:
00377 tls_reason = TLS_ALERT_UNSUPPORTED_CERTIFICATE;
00378 break;
00379 case X509_VALIDATE_CERTIFICATE_REVOKED:
00380 tls_reason = TLS_ALERT_CERTIFICATE_REVOKED;
00381 break;
00382 case X509_VALIDATE_CERTIFICATE_EXPIRED:
00383 tls_reason = TLS_ALERT_CERTIFICATE_EXPIRED;
00384 break;
00385 case X509_VALIDATE_CERTIFICATE_UNKNOWN:
00386 tls_reason = TLS_ALERT_CERTIFICATE_UNKNOWN;
00387 break;
00388 case X509_VALIDATE_UNKNOWN_CA:
00389 tls_reason = TLS_ALERT_UNKNOWN_CA;
00390 break;
00391 default:
00392 tls_reason = TLS_ALERT_BAD_CERTIFICATE;
00393 break;
00394 }
00395 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, tls_reason);
00396 x509_certificate_chain_free(chain);
00397 return -1;
00398 }
00399
00400 x509_certificate_chain_free(chain);
00401
00402 *in_len = end - in_data;
00403
00404 conn->state = SERVER_KEY_EXCHANGE;
00405
00406 return 0;
00407 }
00408
00409
00410 static int tlsv1_process_diffie_hellman(struct tlsv1_client *conn,
00411 const u8 *buf, size_t len)
00412 {
00413 const u8 *pos, *end;
00414
00415 tlsv1_client_free_dh(conn);
00416
00417 pos = buf;
00418 end = buf + len;
00419
00420 if (end - pos < 3)
00421 goto fail;
00422 conn->dh_p_len = WPA_GET_BE16(pos);
00423 pos += 2;
00424 if (conn->dh_p_len == 0 || end - pos < (int) conn->dh_p_len) {
00425 wpa_printf(MSG_DEBUG, "TLSv1: Invalid dh_p length %lu",
00426 (unsigned long) conn->dh_p_len);
00427 goto fail;
00428 }
00429 conn->dh_p = os_malloc(conn->dh_p_len);
00430 if (conn->dh_p == NULL)
00431 goto fail;
00432 os_memcpy(conn->dh_p, pos, conn->dh_p_len);
00433 pos += conn->dh_p_len;
00434 wpa_hexdump(MSG_DEBUG, "TLSv1: DH p (prime)",
00435 conn->dh_p, conn->dh_p_len);
00436
00437 if (end - pos < 3)
00438 goto fail;
00439 conn->dh_g_len = WPA_GET_BE16(pos);
00440 pos += 2;
00441 if (conn->dh_g_len == 0 || end - pos < (int) conn->dh_g_len)
00442 goto fail;
00443 conn->dh_g = os_malloc(conn->dh_g_len);
00444 if (conn->dh_g == NULL)
00445 goto fail;
00446 os_memcpy(conn->dh_g, pos, conn->dh_g_len);
00447 pos += conn->dh_g_len;
00448 wpa_hexdump(MSG_DEBUG, "TLSv1: DH g (generator)",
00449 conn->dh_g, conn->dh_g_len);
00450 if (conn->dh_g_len == 1 && conn->dh_g[0] < 2)
00451 goto fail;
00452
00453 if (end - pos < 3)
00454 goto fail;
00455 conn->dh_ys_len = WPA_GET_BE16(pos);
00456 pos += 2;
00457 if (conn->dh_ys_len == 0 || end - pos < (int) conn->dh_ys_len)
00458 goto fail;
00459 conn->dh_ys = os_malloc(conn->dh_ys_len);
00460 if (conn->dh_ys == NULL)
00461 goto fail;
00462 os_memcpy(conn->dh_ys, pos, conn->dh_ys_len);
00463 pos += conn->dh_ys_len;
00464 wpa_hexdump(MSG_DEBUG, "TLSv1: DH Ys (server's public value)",
00465 conn->dh_ys, conn->dh_ys_len);
00466
00467 return 0;
00468
00469 fail:
00470 wpa_printf(MSG_DEBUG, "TLSv1: Processing DH params failed");
00471 tlsv1_client_free_dh(conn);
00472 return -1;
00473 }
00474
00475
00476 static int tls_process_server_key_exchange(struct tlsv1_client *conn, u8 ct,
00477 const u8 *in_data, size_t *in_len)
00478 {
00479 const u8 *pos, *end;
00480 size_t left, len;
00481 u8 type;
00482 const struct tls_cipher_suite *suite;
00483
00484 if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
00485 wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
00486 "received content type 0x%x", ct);
00487 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00488 TLS_ALERT_UNEXPECTED_MESSAGE);
00489 return -1;
00490 }
00491
00492 pos = in_data;
00493 left = *in_len;
00494
00495 if (left < 4) {
00496 wpa_printf(MSG_DEBUG, "TLSv1: Too short ServerKeyExchange "
00497 "(Left=%lu)", (unsigned long) left);
00498 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
00499 return -1;
00500 }
00501
00502 type = *pos++;
00503 len = WPA_GET_BE24(pos);
00504 pos += 3;
00505 left -= 4;
00506
00507 if (len > left) {
00508 wpa_printf(MSG_DEBUG, "TLSv1: Mismatch in ServerKeyExchange "
00509 "length (len=%lu != left=%lu)",
00510 (unsigned long) len, (unsigned long) left);
00511 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
00512 return -1;
00513 }
00514
00515 end = pos + len;
00516
00517 if (type == TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST)
00518 return tls_process_certificate_request(conn, ct, in_data,
00519 in_len);
00520 if (type == TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE)
00521 return tls_process_server_hello_done(conn, ct, in_data,
00522 in_len);
00523 if (type != TLS_HANDSHAKE_TYPE_SERVER_KEY_EXCHANGE) {
00524 wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
00525 "message %d (expected ServerKeyExchange/"
00526 "CertificateRequest/ServerHelloDone)", type);
00527 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00528 TLS_ALERT_UNEXPECTED_MESSAGE);
00529 return -1;
00530 }
00531
00532 wpa_printf(MSG_DEBUG, "TLSv1: Received ServerKeyExchange");
00533
00534 if (!tls_server_key_exchange_allowed(conn->rl.cipher_suite)) {
00535 wpa_printf(MSG_DEBUG, "TLSv1: ServerKeyExchange not allowed "
00536 "with the selected cipher suite");
00537 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00538 TLS_ALERT_UNEXPECTED_MESSAGE);
00539 return -1;
00540 }
00541
00542 wpa_hexdump(MSG_DEBUG, "TLSv1: ServerKeyExchange", pos, len);
00543 suite = tls_get_cipher_suite(conn->rl.cipher_suite);
00544 if (suite && suite->key_exchange == TLS_KEY_X_DH_anon) {
00545 if (tlsv1_process_diffie_hellman(conn, pos, len) < 0) {
00546 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00547 TLS_ALERT_DECODE_ERROR);
00548 return -1;
00549 }
00550 } else {
00551 wpa_printf(MSG_DEBUG, "TLSv1: UnexpectedServerKeyExchange");
00552 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00553 TLS_ALERT_UNEXPECTED_MESSAGE);
00554 return -1;
00555 }
00556
00557 *in_len = end - in_data;
00558
00559 conn->state = SERVER_CERTIFICATE_REQUEST;
00560
00561 return 0;
00562 }
00563
00564
00565 static int tls_process_certificate_request(struct tlsv1_client *conn, u8 ct,
00566 const u8 *in_data, size_t *in_len)
00567 {
00568 const u8 *pos, *end;
00569 size_t left, len;
00570 u8 type;
00571
00572 if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
00573 wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
00574 "received content type 0x%x", ct);
00575 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00576 TLS_ALERT_UNEXPECTED_MESSAGE);
00577 return -1;
00578 }
00579
00580 pos = in_data;
00581 left = *in_len;
00582
00583 if (left < 4) {
00584 wpa_printf(MSG_DEBUG, "TLSv1: Too short CertificateRequest "
00585 "(left=%lu)", (unsigned long) left);
00586 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
00587 return -1;
00588 }
00589
00590 type = *pos++;
00591 len = WPA_GET_BE24(pos);
00592 pos += 3;
00593 left -= 4;
00594
00595 if (len > left) {
00596 wpa_printf(MSG_DEBUG, "TLSv1: Mismatch in CertificateRequest "
00597 "length (len=%lu != left=%lu)",
00598 (unsigned long) len, (unsigned long) left);
00599 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
00600 return -1;
00601 }
00602
00603 end = pos + len;
00604
00605 if (type == TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE)
00606 return tls_process_server_hello_done(conn, ct, in_data,
00607 in_len);
00608 if (type != TLS_HANDSHAKE_TYPE_CERTIFICATE_REQUEST) {
00609 wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
00610 "message %d (expected CertificateRequest/"
00611 "ServerHelloDone)", type);
00612 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00613 TLS_ALERT_UNEXPECTED_MESSAGE);
00614 return -1;
00615 }
00616
00617 wpa_printf(MSG_DEBUG, "TLSv1: Received CertificateRequest");
00618
00619 conn->certificate_requested = 1;
00620
00621 *in_len = end - in_data;
00622
00623 conn->state = SERVER_HELLO_DONE;
00624
00625 return 0;
00626 }
00627
00628
00629 static int tls_process_server_hello_done(struct tlsv1_client *conn, u8 ct,
00630 const u8 *in_data, size_t *in_len)
00631 {
00632 const u8 *pos, *end;
00633 size_t left, len;
00634 u8 type;
00635
00636 if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
00637 wpa_printf(MSG_DEBUG, "TLSv1: Expected Handshake; "
00638 "received content type 0x%x", ct);
00639 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00640 TLS_ALERT_UNEXPECTED_MESSAGE);
00641 return -1;
00642 }
00643
00644 pos = in_data;
00645 left = *in_len;
00646
00647 if (left < 4) {
00648 wpa_printf(MSG_DEBUG, "TLSv1: Too short ServerHelloDone "
00649 "(left=%lu)", (unsigned long) left);
00650 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
00651 return -1;
00652 }
00653
00654 type = *pos++;
00655 len = WPA_GET_BE24(pos);
00656 pos += 3;
00657 left -= 4;
00658
00659 if (len > left) {
00660 wpa_printf(MSG_DEBUG, "TLSv1: Mismatch in ServerHelloDone "
00661 "length (len=%lu != left=%lu)",
00662 (unsigned long) len, (unsigned long) left);
00663 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
00664 return -1;
00665 }
00666 end = pos + len;
00667
00668 if (type != TLS_HANDSHAKE_TYPE_SERVER_HELLO_DONE) {
00669 wpa_printf(MSG_DEBUG, "TLSv1: Received unexpected handshake "
00670 "message %d (expected ServerHelloDone)", type);
00671 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00672 TLS_ALERT_UNEXPECTED_MESSAGE);
00673 return -1;
00674 }
00675
00676 wpa_printf(MSG_DEBUG, "TLSv1: Received ServerHelloDone");
00677
00678 *in_len = end - in_data;
00679
00680 conn->state = CLIENT_KEY_EXCHANGE;
00681
00682 return 0;
00683 }
00684
00685
00686 static int tls_process_server_change_cipher_spec(struct tlsv1_client *conn,
00687 u8 ct, const u8 *in_data,
00688 size_t *in_len)
00689 {
00690 const u8 *pos;
00691 size_t left;
00692
00693 if (ct != TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC) {
00694 wpa_printf(MSG_DEBUG, "TLSv1: Expected ChangeCipherSpec; "
00695 "received content type 0x%x", ct);
00696 if (conn->use_session_ticket) {
00697 int res;
00698 wpa_printf(MSG_DEBUG, "TLSv1: Server may have "
00699 "rejected SessionTicket");
00700 conn->use_session_ticket = 0;
00701
00702
00703 res = conn->session_ticket_cb(
00704 conn->session_ticket_cb_ctx, NULL, 0, NULL,
00705 NULL, NULL);
00706 if (res < 0) {
00707 wpa_printf(MSG_DEBUG, "TLSv1: SessionTicket "
00708 "callback indicated failure");
00709 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00710 TLS_ALERT_HANDSHAKE_FAILURE);
00711 return -1;
00712 }
00713
00714 conn->state = SERVER_CERTIFICATE;
00715 return tls_process_certificate(conn, ct, in_data,
00716 in_len);
00717 }
00718 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00719 TLS_ALERT_UNEXPECTED_MESSAGE);
00720 return -1;
00721 }
00722
00723 pos = in_data;
00724 left = *in_len;
00725
00726 if (left < 1) {
00727 wpa_printf(MSG_DEBUG, "TLSv1: Too short ChangeCipherSpec");
00728 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_DECODE_ERROR);
00729 return -1;
00730 }
00731
00732 if (*pos != TLS_CHANGE_CIPHER_SPEC) {
00733 wpa_printf(MSG_DEBUG, "TLSv1: Expected ChangeCipherSpec; "
00734 "received data 0x%x", *pos);
00735 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00736 TLS_ALERT_UNEXPECTED_MESSAGE);
00737 return -1;
00738 }
00739
00740 wpa_printf(MSG_DEBUG, "TLSv1: Received ChangeCipherSpec");
00741 if (tlsv1_record_change_read_cipher(&conn->rl) < 0) {
00742 wpa_printf(MSG_DEBUG, "TLSv1: Failed to change read cipher "
00743 "for record layer");
00744 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00745 TLS_ALERT_INTERNAL_ERROR);
00746 return -1;
00747 }
00748
00749 *in_len = pos + 1 - in_data;
00750
00751 conn->state = SERVER_FINISHED;
00752
00753 return 0;
00754 }
00755
00756
00757 static int tls_process_server_finished(struct tlsv1_client *conn, u8 ct,
00758 const u8 *in_data, size_t *in_len)
00759 {
00760 const u8 *pos, *end;
00761 size_t left, len, hlen;
00762 u8 verify_data[TLS_VERIFY_DATA_LEN];
00763 u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN];
00764
00765 if (ct != TLS_CONTENT_TYPE_HANDSHAKE) {
00766 wpa_printf(MSG_DEBUG, "TLSv1: Expected Finished; "
00767 "received content type 0x%x", ct);
00768 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00769 TLS_ALERT_UNEXPECTED_MESSAGE);
00770 return -1;
00771 }
00772
00773 pos = in_data;
00774 left = *in_len;
00775
00776 if (left < 4) {
00777 wpa_printf(MSG_DEBUG, "TLSv1: Too short record (left=%lu) for "
00778 "Finished",
00779 (unsigned long) left);
00780 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00781 TLS_ALERT_DECODE_ERROR);
00782 return -1;
00783 }
00784
00785 if (pos[0] != TLS_HANDSHAKE_TYPE_FINISHED) {
00786 wpa_printf(MSG_DEBUG, "TLSv1: Expected Finished; received "
00787 "type 0x%x", pos[0]);
00788 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00789 TLS_ALERT_UNEXPECTED_MESSAGE);
00790 return -1;
00791 }
00792
00793 len = WPA_GET_BE24(pos + 1);
00794
00795 pos += 4;
00796 left -= 4;
00797
00798 if (len > left) {
00799 wpa_printf(MSG_DEBUG, "TLSv1: Too short buffer for Finished "
00800 "(len=%lu > left=%lu)",
00801 (unsigned long) len, (unsigned long) left);
00802 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00803 TLS_ALERT_DECODE_ERROR);
00804 return -1;
00805 }
00806 end = pos + len;
00807 if (len != TLS_VERIFY_DATA_LEN) {
00808 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected verify_data length "
00809 "in Finished: %lu (expected %d)",
00810 (unsigned long) len, TLS_VERIFY_DATA_LEN);
00811 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00812 TLS_ALERT_DECODE_ERROR);
00813 return -1;
00814 }
00815 wpa_hexdump(MSG_MSGDUMP, "TLSv1: verify_data in Finished",
00816 pos, TLS_VERIFY_DATA_LEN);
00817
00818 hlen = MD5_MAC_LEN;
00819 if (conn->verify.md5_server == NULL ||
00820 crypto_hash_finish(conn->verify.md5_server, hash, &hlen) < 0) {
00821 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00822 TLS_ALERT_INTERNAL_ERROR);
00823 conn->verify.md5_server = NULL;
00824 crypto_hash_finish(conn->verify.sha1_server, NULL, NULL);
00825 conn->verify.sha1_server = NULL;
00826 return -1;
00827 }
00828 conn->verify.md5_server = NULL;
00829 hlen = SHA1_MAC_LEN;
00830 if (conn->verify.sha1_server == NULL ||
00831 crypto_hash_finish(conn->verify.sha1_server, hash + MD5_MAC_LEN,
00832 &hlen) < 0) {
00833 conn->verify.sha1_server = NULL;
00834 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00835 TLS_ALERT_INTERNAL_ERROR);
00836 return -1;
00837 }
00838 conn->verify.sha1_server = NULL;
00839
00840 if (tls_prf(conn->master_secret, TLS_MASTER_SECRET_LEN,
00841 "server finished", hash, MD5_MAC_LEN + SHA1_MAC_LEN,
00842 verify_data, TLS_VERIFY_DATA_LEN)) {
00843 wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive verify_data");
00844 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00845 TLS_ALERT_DECRYPT_ERROR);
00846 return -1;
00847 }
00848 wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (server)",
00849 verify_data, TLS_VERIFY_DATA_LEN);
00850
00851 if (os_memcmp(pos, verify_data, TLS_VERIFY_DATA_LEN) != 0) {
00852 wpa_printf(MSG_INFO, "TLSv1: Mismatch in verify_data");
00853 return -1;
00854 }
00855
00856 wpa_printf(MSG_DEBUG, "TLSv1: Received Finished");
00857
00858 *in_len = end - in_data;
00859
00860 conn->state = (conn->session_resumed || conn->use_session_ticket) ?
00861 CHANGE_CIPHER_SPEC : ACK_FINISHED;
00862
00863 return 0;
00864 }
00865
00866
00867 static int tls_process_application_data(struct tlsv1_client *conn, u8 ct,
00868 const u8 *in_data, size_t *in_len,
00869 u8 **out_data, size_t *out_len)
00870 {
00871 const u8 *pos;
00872 size_t left;
00873
00874 if (ct != TLS_CONTENT_TYPE_APPLICATION_DATA) {
00875 wpa_printf(MSG_DEBUG, "TLSv1: Expected Application Data; "
00876 "received content type 0x%x", ct);
00877 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00878 TLS_ALERT_UNEXPECTED_MESSAGE);
00879 return -1;
00880 }
00881
00882 pos = in_data;
00883 left = *in_len;
00884
00885 wpa_hexdump(MSG_DEBUG, "TLSv1: Application Data included in Handshake",
00886 pos, left);
00887
00888 *out_data = os_malloc(left);
00889 if (*out_data) {
00890 os_memcpy(*out_data, pos, left);
00891 *out_len = left;
00892 }
00893
00894 return 0;
00895 }
00896
00897
00898 int tlsv1_client_process_handshake(struct tlsv1_client *conn, u8 ct,
00899 const u8 *buf, size_t *len,
00900 u8 **out_data, size_t *out_len)
00901 {
00902 if (ct == TLS_CONTENT_TYPE_ALERT) {
00903 if (*len < 2) {
00904 wpa_printf(MSG_DEBUG, "TLSv1: Alert underflow");
00905 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00906 TLS_ALERT_DECODE_ERROR);
00907 return -1;
00908 }
00909 wpa_printf(MSG_DEBUG, "TLSv1: Received alert %d:%d",
00910 buf[0], buf[1]);
00911 *len = 2;
00912 conn->state = FAILED;
00913 return -1;
00914 }
00915
00916 if (ct == TLS_CONTENT_TYPE_HANDSHAKE && *len >= 4 &&
00917 buf[0] == TLS_HANDSHAKE_TYPE_HELLO_REQUEST) {
00918 size_t hr_len = WPA_GET_BE24(buf + 1);
00919 if (hr_len > *len - 4) {
00920 wpa_printf(MSG_DEBUG, "TLSv1: HelloRequest underflow");
00921 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00922 TLS_ALERT_DECODE_ERROR);
00923 return -1;
00924 }
00925 wpa_printf(MSG_DEBUG, "TLSv1: Ignored HelloRequest");
00926 *len = 4 + hr_len;
00927 return 0;
00928 }
00929
00930 switch (conn->state) {
00931 case SERVER_HELLO:
00932 if (tls_process_server_hello(conn, ct, buf, len))
00933 return -1;
00934 break;
00935 case SERVER_CERTIFICATE:
00936 if (tls_process_certificate(conn, ct, buf, len))
00937 return -1;
00938 break;
00939 case SERVER_KEY_EXCHANGE:
00940 if (tls_process_server_key_exchange(conn, ct, buf, len))
00941 return -1;
00942 break;
00943 case SERVER_CERTIFICATE_REQUEST:
00944 if (tls_process_certificate_request(conn, ct, buf, len))
00945 return -1;
00946 break;
00947 case SERVER_HELLO_DONE:
00948 if (tls_process_server_hello_done(conn, ct, buf, len))
00949 return -1;
00950 break;
00951 case SERVER_CHANGE_CIPHER_SPEC:
00952 if (tls_process_server_change_cipher_spec(conn, ct, buf, len))
00953 return -1;
00954 break;
00955 case SERVER_FINISHED:
00956 if (tls_process_server_finished(conn, ct, buf, len))
00957 return -1;
00958 break;
00959 case ACK_FINISHED:
00960 if (out_data &&
00961 tls_process_application_data(conn, ct, buf, len, out_data,
00962 out_len))
00963 return -1;
00964 break;
00965 default:
00966 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected state %d "
00967 "while processing received message",
00968 conn->state);
00969 return -1;
00970 }
00971
00972 if (ct == TLS_CONTENT_TYPE_HANDSHAKE)
00973 tls_verify_hash_add(&conn->verify, buf, *len);
00974
00975 return 0;
00976 }