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