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
00029 static size_t tls_client_cert_chain_der_len(struct tlsv1_client *conn)
00030 {
00031 size_t len = 0;
00032 struct x509_certificate *cert;
00033
00034 if (conn->cred == NULL)
00035 return 0;
00036
00037 cert = conn->cred->cert;
00038 while (cert) {
00039 len += 3 + cert->cert_len;
00040 if (x509_certificate_self_signed(cert))
00041 break;
00042 cert = x509_certificate_get_subject(conn->cred->trusted_certs,
00043 &cert->issuer);
00044 }
00045
00046 return len;
00047 }
00048
00049
00050 u8 * tls_send_client_hello(struct tlsv1_client *conn, size_t *out_len)
00051 {
00052 u8 *hello, *end, *pos, *hs_length, *hs_start, *rhdr;
00053 struct os_time now;
00054 size_t len, i;
00055
00056 wpa_printf(MSG_DEBUG, "TLSv1: Send ClientHello");
00057 *out_len = 0;
00058
00059 os_get_time(&now);
00060 WPA_PUT_BE32(conn->client_random, now.sec);
00061 if (os_get_random(conn->client_random + 4, TLS_RANDOM_LEN - 4)) {
00062 wpa_printf(MSG_ERROR, "TLSv1: Could not generate "
00063 "client_random");
00064 return NULL;
00065 }
00066 wpa_hexdump(MSG_MSGDUMP, "TLSv1: client_random",
00067 conn->client_random, TLS_RANDOM_LEN);
00068
00069 len = 100 + conn->num_cipher_suites * 2 + conn->client_hello_ext_len;
00070 hello = os_malloc(len);
00071 if (hello == NULL)
00072 return NULL;
00073 end = hello + len;
00074
00075 rhdr = hello;
00076 pos = rhdr + TLS_RECORD_HEADER_LEN;
00077
00078
00079
00080
00081 hs_start = pos;
00082
00083 *pos++ = TLS_HANDSHAKE_TYPE_CLIENT_HELLO;
00084
00085 hs_length = pos;
00086 pos += 3;
00087
00088
00089 WPA_PUT_BE16(pos, TLS_VERSION);
00090 pos += 2;
00091
00092 os_memcpy(pos, conn->client_random, TLS_RANDOM_LEN);
00093 pos += TLS_RANDOM_LEN;
00094
00095 *pos++ = conn->session_id_len;
00096 os_memcpy(pos, conn->session_id, conn->session_id_len);
00097 pos += conn->session_id_len;
00098
00099 WPA_PUT_BE16(pos, 2 * conn->num_cipher_suites);
00100 pos += 2;
00101 for (i = 0; i < conn->num_cipher_suites; i++) {
00102 WPA_PUT_BE16(pos, conn->cipher_suites[i]);
00103 pos += 2;
00104 }
00105
00106 *pos++ = 1;
00107 *pos++ = TLS_COMPRESSION_NULL;
00108
00109 if (conn->client_hello_ext) {
00110 os_memcpy(pos, conn->client_hello_ext,
00111 conn->client_hello_ext_len);
00112 pos += conn->client_hello_ext_len;
00113 }
00114
00115 WPA_PUT_BE24(hs_length, pos - hs_length - 3);
00116 tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start);
00117
00118 if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
00119 rhdr, end - rhdr, pos - hs_start, out_len) < 0) {
00120 wpa_printf(MSG_DEBUG, "TLSv1: Failed to create TLS record");
00121 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00122 TLS_ALERT_INTERNAL_ERROR);
00123 os_free(hello);
00124 return NULL;
00125 }
00126
00127 conn->state = SERVER_HELLO;
00128
00129 return hello;
00130 }
00131
00132
00133 static int tls_write_client_certificate(struct tlsv1_client *conn,
00134 u8 **msgpos, u8 *end)
00135 {
00136 u8 *pos, *rhdr, *hs_start, *hs_length, *cert_start;
00137 size_t rlen;
00138 struct x509_certificate *cert;
00139
00140 pos = *msgpos;
00141
00142 wpa_printf(MSG_DEBUG, "TLSv1: Send Certificate");
00143 rhdr = pos;
00144 pos += TLS_RECORD_HEADER_LEN;
00145
00146
00147
00148
00149 hs_start = pos;
00150
00151 *pos++ = TLS_HANDSHAKE_TYPE_CERTIFICATE;
00152
00153 hs_length = pos;
00154 pos += 3;
00155
00156
00157 cert_start = pos;
00158 pos += 3;
00159 cert = conn->cred ? conn->cred->cert : NULL;
00160 while (cert) {
00161 if (pos + 3 + cert->cert_len > end) {
00162 wpa_printf(MSG_DEBUG, "TLSv1: Not enough buffer space "
00163 "for Certificate (cert_len=%lu left=%lu)",
00164 (unsigned long) cert->cert_len,
00165 (unsigned long) (end - pos));
00166 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00167 TLS_ALERT_INTERNAL_ERROR);
00168 return -1;
00169 }
00170 WPA_PUT_BE24(pos, cert->cert_len);
00171 pos += 3;
00172 os_memcpy(pos, cert->cert_start, cert->cert_len);
00173 pos += cert->cert_len;
00174
00175 if (x509_certificate_self_signed(cert))
00176 break;
00177 cert = x509_certificate_get_subject(conn->cred->trusted_certs,
00178 &cert->issuer);
00179 }
00180 if (conn->cred == NULL || cert == conn->cred->cert || cert == NULL) {
00181
00182
00183
00184
00185
00186
00187 wpa_printf(MSG_DEBUG, "TLSv1: Full client certificate chain "
00188 "not configured - validation may fail");
00189 }
00190 WPA_PUT_BE24(cert_start, pos - cert_start - 3);
00191
00192 WPA_PUT_BE24(hs_length, pos - hs_length - 3);
00193
00194 if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
00195 rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
00196 wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record");
00197 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00198 TLS_ALERT_INTERNAL_ERROR);
00199 return -1;
00200 }
00201 pos = rhdr + rlen;
00202
00203 tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start);
00204
00205 *msgpos = pos;
00206
00207 return 0;
00208 }
00209
00210
00211 static int tlsv1_key_x_anon_dh(struct tlsv1_client *conn, u8 **pos, u8 *end)
00212 {
00213 #ifdef EAP_FAST
00214
00215 u8 *csecret, *csecret_start, *dh_yc, *shared;
00216 size_t csecret_len, dh_yc_len, shared_len;
00217
00218 csecret_len = conn->dh_p_len;
00219 csecret = os_malloc(csecret_len);
00220 if (csecret == NULL) {
00221 wpa_printf(MSG_DEBUG, "TLSv1: Failed to allocate "
00222 "memory for Yc (Diffie-Hellman)");
00223 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00224 TLS_ALERT_INTERNAL_ERROR);
00225 return -1;
00226 }
00227 if (os_get_random(csecret, csecret_len)) {
00228 wpa_printf(MSG_DEBUG, "TLSv1: Failed to get random "
00229 "data for Diffie-Hellman");
00230 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00231 TLS_ALERT_INTERNAL_ERROR);
00232 os_free(csecret);
00233 return -1;
00234 }
00235
00236 if (os_memcmp(csecret, conn->dh_p, csecret_len) > 0)
00237 csecret[0] = 0;
00238
00239 csecret_start = csecret;
00240 while (csecret_len > 1 && *csecret_start == 0) {
00241 csecret_start++;
00242 csecret_len--;
00243 }
00244 wpa_hexdump_key(MSG_DEBUG, "TLSv1: DH client's secret value",
00245 csecret_start, csecret_len);
00246
00247
00248 dh_yc_len = conn->dh_p_len;
00249 dh_yc = os_malloc(dh_yc_len);
00250 if (dh_yc == NULL) {
00251 wpa_printf(MSG_DEBUG, "TLSv1: Failed to allocate "
00252 "memory for Diffie-Hellman");
00253 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00254 TLS_ALERT_INTERNAL_ERROR);
00255 os_free(csecret);
00256 return -1;
00257 }
00258 if (crypto_mod_exp(conn->dh_g, conn->dh_g_len,
00259 csecret_start, csecret_len,
00260 conn->dh_p, conn->dh_p_len,
00261 dh_yc, &dh_yc_len)) {
00262 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00263 TLS_ALERT_INTERNAL_ERROR);
00264 os_free(csecret);
00265 os_free(dh_yc);
00266 return -1;
00267 }
00268
00269 wpa_hexdump(MSG_DEBUG, "TLSv1: DH Yc (client's public value)",
00270 dh_yc, dh_yc_len);
00271
00272 WPA_PUT_BE16(*pos, dh_yc_len);
00273 *pos += 2;
00274 if (*pos + dh_yc_len > end) {
00275 wpa_printf(MSG_DEBUG, "TLSv1: Not enough room in the "
00276 "message buffer for Yc");
00277 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00278 TLS_ALERT_INTERNAL_ERROR);
00279 os_free(csecret);
00280 os_free(dh_yc);
00281 return -1;
00282 }
00283 os_memcpy(*pos, dh_yc, dh_yc_len);
00284 *pos += dh_yc_len;
00285 os_free(dh_yc);
00286
00287 shared_len = conn->dh_p_len;
00288 shared = os_malloc(shared_len);
00289 if (shared == NULL) {
00290 wpa_printf(MSG_DEBUG, "TLSv1: Could not allocate memory for "
00291 "DH");
00292 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00293 TLS_ALERT_INTERNAL_ERROR);
00294 os_free(csecret);
00295 return -1;
00296 }
00297
00298
00299 if (crypto_mod_exp(conn->dh_ys, conn->dh_ys_len,
00300 csecret_start, csecret_len,
00301 conn->dh_p, conn->dh_p_len,
00302 shared, &shared_len)) {
00303 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00304 TLS_ALERT_INTERNAL_ERROR);
00305 os_free(csecret);
00306 os_free(shared);
00307 return -1;
00308 }
00309 wpa_hexdump_key(MSG_DEBUG, "TLSv1: Shared secret from DH key exchange",
00310 shared, shared_len);
00311
00312 os_memset(csecret_start, 0, csecret_len);
00313 os_free(csecret);
00314 if (tls_derive_keys(conn, shared, shared_len)) {
00315 wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive keys");
00316 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00317 TLS_ALERT_INTERNAL_ERROR);
00318 os_free(shared);
00319 return -1;
00320 }
00321 os_memset(shared, 0, shared_len);
00322 os_free(shared);
00323 tlsv1_client_free_dh(conn);
00324 return 0;
00325 #else
00326 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, TLS_ALERT_INTERNAL_ERROR);
00327 return -1;
00328 #endif
00329 }
00330
00331
00332 static int tlsv1_key_x_rsa(struct tlsv1_client *conn, u8 **pos, u8 *end)
00333 {
00334 u8 pre_master_secret[TLS_PRE_MASTER_SECRET_LEN];
00335 size_t clen;
00336 int res;
00337
00338 if (tls_derive_pre_master_secret(pre_master_secret) < 0 ||
00339 tls_derive_keys(conn, pre_master_secret,
00340 TLS_PRE_MASTER_SECRET_LEN)) {
00341 wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive keys");
00342 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00343 TLS_ALERT_INTERNAL_ERROR);
00344 return -1;
00345 }
00346
00347
00348 if (conn->server_rsa_key == NULL) {
00349 wpa_printf(MSG_DEBUG, "TLSv1: No server RSA key to "
00350 "use for encrypting pre-master secret");
00351 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00352 TLS_ALERT_INTERNAL_ERROR);
00353 return -1;
00354 }
00355
00356
00357 *pos += 2;
00358 clen = end - *pos;
00359 res = crypto_public_key_encrypt_pkcs1_v15(
00360 conn->server_rsa_key,
00361 pre_master_secret, TLS_PRE_MASTER_SECRET_LEN,
00362 *pos, &clen);
00363 os_memset(pre_master_secret, 0, TLS_PRE_MASTER_SECRET_LEN);
00364 if (res < 0) {
00365 wpa_printf(MSG_DEBUG, "TLSv1: RSA encryption failed");
00366 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00367 TLS_ALERT_INTERNAL_ERROR);
00368 return -1;
00369 }
00370 WPA_PUT_BE16(*pos - 2, clen);
00371 wpa_hexdump(MSG_MSGDUMP, "TLSv1: Encrypted pre_master_secret",
00372 *pos, clen);
00373 *pos += clen;
00374
00375 return 0;
00376 }
00377
00378
00379 static int tls_write_client_key_exchange(struct tlsv1_client *conn,
00380 u8 **msgpos, u8 *end)
00381 {
00382 u8 *pos, *rhdr, *hs_start, *hs_length;
00383 size_t rlen;
00384 tls_key_exchange keyx;
00385 const struct tls_cipher_suite *suite;
00386
00387 suite = tls_get_cipher_suite(conn->rl.cipher_suite);
00388 if (suite == NULL)
00389 keyx = TLS_KEY_X_NULL;
00390 else
00391 keyx = suite->key_exchange;
00392
00393 pos = *msgpos;
00394
00395 wpa_printf(MSG_DEBUG, "TLSv1: Send ClientKeyExchange");
00396
00397 rhdr = pos;
00398 pos += TLS_RECORD_HEADER_LEN;
00399
00400
00401
00402
00403 hs_start = pos;
00404
00405 *pos++ = TLS_HANDSHAKE_TYPE_CLIENT_KEY_EXCHANGE;
00406
00407 hs_length = pos;
00408 pos += 3;
00409
00410 if (keyx == TLS_KEY_X_DH_anon) {
00411 if (tlsv1_key_x_anon_dh(conn, &pos, end) < 0)
00412 return -1;
00413 } else {
00414 if (tlsv1_key_x_rsa(conn, &pos, end) < 0)
00415 return -1;
00416 }
00417
00418 WPA_PUT_BE24(hs_length, pos - hs_length - 3);
00419
00420 if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
00421 rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
00422 wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
00423 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00424 TLS_ALERT_INTERNAL_ERROR);
00425 return -1;
00426 }
00427 pos = rhdr + rlen;
00428 tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start);
00429
00430 *msgpos = pos;
00431
00432 return 0;
00433 }
00434
00435
00436 static int tls_write_client_certificate_verify(struct tlsv1_client *conn,
00437 u8 **msgpos, u8 *end)
00438 {
00439 u8 *pos, *rhdr, *hs_start, *hs_length, *signed_start;
00440 size_t rlen, hlen, clen;
00441 u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN], *hpos;
00442 enum { SIGN_ALG_RSA, SIGN_ALG_DSA } alg = SIGN_ALG_RSA;
00443
00444 pos = *msgpos;
00445
00446 wpa_printf(MSG_DEBUG, "TLSv1: Send CertificateVerify");
00447 rhdr = pos;
00448 pos += TLS_RECORD_HEADER_LEN;
00449
00450
00451 hs_start = pos;
00452
00453 *pos++ = TLS_HANDSHAKE_TYPE_CERTIFICATE_VERIFY;
00454
00455 hs_length = pos;
00456 pos += 3;
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479 hpos = hash;
00480
00481 if (alg == SIGN_ALG_RSA) {
00482 hlen = MD5_MAC_LEN;
00483 if (conn->verify.md5_cert == NULL ||
00484 crypto_hash_finish(conn->verify.md5_cert, hpos, &hlen) < 0)
00485 {
00486 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00487 TLS_ALERT_INTERNAL_ERROR);
00488 conn->verify.md5_cert = NULL;
00489 crypto_hash_finish(conn->verify.sha1_cert, NULL, NULL);
00490 conn->verify.sha1_cert = NULL;
00491 return -1;
00492 }
00493 hpos += MD5_MAC_LEN;
00494 } else
00495 crypto_hash_finish(conn->verify.md5_cert, NULL, NULL);
00496
00497 conn->verify.md5_cert = NULL;
00498 hlen = SHA1_MAC_LEN;
00499 if (conn->verify.sha1_cert == NULL ||
00500 crypto_hash_finish(conn->verify.sha1_cert, hpos, &hlen) < 0) {
00501 conn->verify.sha1_cert = NULL;
00502 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00503 TLS_ALERT_INTERNAL_ERROR);
00504 return -1;
00505 }
00506 conn->verify.sha1_cert = NULL;
00507
00508 if (alg == SIGN_ALG_RSA)
00509 hlen += MD5_MAC_LEN;
00510
00511 wpa_hexdump(MSG_MSGDUMP, "TLSv1: CertificateVerify hash", hash, hlen);
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524 signed_start = pos;
00525 pos += 2;
00526 clen = end - pos;
00527 if (conn->cred == NULL ||
00528 crypto_private_key_sign_pkcs1(conn->cred->key, hash, hlen,
00529 pos, &clen) < 0) {
00530 wpa_printf(MSG_DEBUG, "TLSv1: Failed to sign hash (PKCS #1)");
00531 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00532 TLS_ALERT_INTERNAL_ERROR);
00533 return -1;
00534 }
00535 WPA_PUT_BE16(signed_start, clen);
00536
00537 pos += clen;
00538
00539 WPA_PUT_BE24(hs_length, pos - hs_length - 3);
00540
00541 if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
00542 rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
00543 wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate a record");
00544 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00545 TLS_ALERT_INTERNAL_ERROR);
00546 return -1;
00547 }
00548 pos = rhdr + rlen;
00549
00550 tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start);
00551
00552 *msgpos = pos;
00553
00554 return 0;
00555 }
00556
00557
00558 static int tls_write_client_change_cipher_spec(struct tlsv1_client *conn,
00559 u8 **msgpos, u8 *end)
00560 {
00561 u8 *pos, *rhdr;
00562 size_t rlen;
00563
00564 pos = *msgpos;
00565
00566 wpa_printf(MSG_DEBUG, "TLSv1: Send ChangeCipherSpec");
00567 rhdr = pos;
00568 pos += TLS_RECORD_HEADER_LEN;
00569 *pos = TLS_CHANGE_CIPHER_SPEC;
00570 if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_CHANGE_CIPHER_SPEC,
00571 rhdr, end - rhdr, 1, &rlen) < 0) {
00572 wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
00573 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00574 TLS_ALERT_INTERNAL_ERROR);
00575 return -1;
00576 }
00577
00578 if (tlsv1_record_change_write_cipher(&conn->rl) < 0) {
00579 wpa_printf(MSG_DEBUG, "TLSv1: Failed to set write cipher for "
00580 "record layer");
00581 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00582 TLS_ALERT_INTERNAL_ERROR);
00583 return -1;
00584 }
00585
00586 *msgpos = rhdr + rlen;
00587
00588 return 0;
00589 }
00590
00591
00592 static int tls_write_client_finished(struct tlsv1_client *conn,
00593 u8 **msgpos, u8 *end)
00594 {
00595 u8 *pos, *rhdr, *hs_start, *hs_length;
00596 size_t rlen, hlen;
00597 u8 verify_data[TLS_VERIFY_DATA_LEN];
00598 u8 hash[MD5_MAC_LEN + SHA1_MAC_LEN];
00599
00600 pos = *msgpos;
00601
00602 wpa_printf(MSG_DEBUG, "TLSv1: Send Finished");
00603
00604
00605
00606 hlen = MD5_MAC_LEN;
00607 if (conn->verify.md5_client == NULL ||
00608 crypto_hash_finish(conn->verify.md5_client, hash, &hlen) < 0) {
00609 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00610 TLS_ALERT_INTERNAL_ERROR);
00611 conn->verify.md5_client = NULL;
00612 crypto_hash_finish(conn->verify.sha1_client, NULL, NULL);
00613 conn->verify.sha1_client = NULL;
00614 return -1;
00615 }
00616 conn->verify.md5_client = NULL;
00617 hlen = SHA1_MAC_LEN;
00618 if (conn->verify.sha1_client == NULL ||
00619 crypto_hash_finish(conn->verify.sha1_client, hash + MD5_MAC_LEN,
00620 &hlen) < 0) {
00621 conn->verify.sha1_client = NULL;
00622 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00623 TLS_ALERT_INTERNAL_ERROR);
00624 return -1;
00625 }
00626 conn->verify.sha1_client = NULL;
00627
00628 if (tls_prf(conn->master_secret, TLS_MASTER_SECRET_LEN,
00629 "client finished", hash, MD5_MAC_LEN + SHA1_MAC_LEN,
00630 verify_data, TLS_VERIFY_DATA_LEN)) {
00631 wpa_printf(MSG_DEBUG, "TLSv1: Failed to generate verify_data");
00632 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00633 TLS_ALERT_INTERNAL_ERROR);
00634 return -1;
00635 }
00636 wpa_hexdump_key(MSG_DEBUG, "TLSv1: verify_data (client)",
00637 verify_data, TLS_VERIFY_DATA_LEN);
00638
00639 rhdr = pos;
00640 pos += TLS_RECORD_HEADER_LEN;
00641
00642 hs_start = pos;
00643
00644 *pos++ = TLS_HANDSHAKE_TYPE_FINISHED;
00645
00646 hs_length = pos;
00647 pos += 3;
00648 os_memcpy(pos, verify_data, TLS_VERIFY_DATA_LEN);
00649 pos += TLS_VERIFY_DATA_LEN;
00650 WPA_PUT_BE24(hs_length, pos - hs_length - 3);
00651 tls_verify_hash_add(&conn->verify, hs_start, pos - hs_start);
00652
00653 if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_HANDSHAKE,
00654 rhdr, end - rhdr, pos - hs_start, &rlen) < 0) {
00655 wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
00656 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00657 TLS_ALERT_INTERNAL_ERROR);
00658 return -1;
00659 }
00660
00661 pos = rhdr + rlen;
00662
00663 *msgpos = pos;
00664
00665 return 0;
00666 }
00667
00668
00669 static u8 * tls_send_client_key_exchange(struct tlsv1_client *conn,
00670 size_t *out_len)
00671 {
00672 u8 *msg, *end, *pos;
00673 size_t msglen;
00674
00675 *out_len = 0;
00676
00677 msglen = 1000;
00678 if (conn->certificate_requested)
00679 msglen += tls_client_cert_chain_der_len(conn);
00680
00681 msg = os_malloc(msglen);
00682 if (msg == NULL)
00683 return NULL;
00684
00685 pos = msg;
00686 end = msg + msglen;
00687
00688 if (conn->certificate_requested) {
00689 if (tls_write_client_certificate(conn, &pos, end) < 0) {
00690 os_free(msg);
00691 return NULL;
00692 }
00693 }
00694
00695 if (tls_write_client_key_exchange(conn, &pos, end) < 0 ||
00696 (conn->certificate_requested && conn->cred && conn->cred->key &&
00697 tls_write_client_certificate_verify(conn, &pos, end) < 0) ||
00698 tls_write_client_change_cipher_spec(conn, &pos, end) < 0 ||
00699 tls_write_client_finished(conn, &pos, end) < 0) {
00700 os_free(msg);
00701 return NULL;
00702 }
00703
00704 *out_len = pos - msg;
00705
00706 conn->state = SERVER_CHANGE_CIPHER_SPEC;
00707
00708 return msg;
00709 }
00710
00711
00712 static u8 * tls_send_change_cipher_spec(struct tlsv1_client *conn,
00713 size_t *out_len)
00714 {
00715 u8 *msg, *end, *pos;
00716
00717 *out_len = 0;
00718
00719 msg = os_malloc(1000);
00720 if (msg == NULL)
00721 return NULL;
00722
00723 pos = msg;
00724 end = msg + 1000;
00725
00726 if (tls_write_client_change_cipher_spec(conn, &pos, end) < 0 ||
00727 tls_write_client_finished(conn, &pos, end) < 0) {
00728 os_free(msg);
00729 return NULL;
00730 }
00731
00732 *out_len = pos - msg;
00733
00734 wpa_printf(MSG_DEBUG, "TLSv1: Session resumption completed "
00735 "successfully");
00736 conn->state = ESTABLISHED;
00737
00738 return msg;
00739 }
00740
00741
00742 u8 * tlsv1_client_handshake_write(struct tlsv1_client *conn, size_t *out_len,
00743 int no_appl_data)
00744 {
00745 switch (conn->state) {
00746 case CLIENT_KEY_EXCHANGE:
00747 return tls_send_client_key_exchange(conn, out_len);
00748 case CHANGE_CIPHER_SPEC:
00749 return tls_send_change_cipher_spec(conn, out_len);
00750 case ACK_FINISHED:
00751 wpa_printf(MSG_DEBUG, "TLSv1: Handshake completed "
00752 "successfully");
00753 conn->state = ESTABLISHED;
00754 *out_len = 0;
00755 if (no_appl_data) {
00756
00757 return os_malloc(1);
00758 }
00759 return NULL;
00760 default:
00761 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected state %d while "
00762 "generating reply", conn->state);
00763 return NULL;
00764 }
00765 }
00766
00767
00768 u8 * tlsv1_client_send_alert(struct tlsv1_client *conn, u8 level,
00769 u8 description, size_t *out_len)
00770 {
00771 u8 *alert, *pos, *length;
00772
00773 wpa_printf(MSG_DEBUG, "TLSv1: Send Alert(%d:%d)", level, description);
00774 *out_len = 0;
00775
00776 alert = os_malloc(10);
00777 if (alert == NULL)
00778 return NULL;
00779
00780 pos = alert;
00781
00782
00783
00784 *pos++ = TLS_CONTENT_TYPE_ALERT;
00785
00786 WPA_PUT_BE16(pos, TLS_VERSION);
00787 pos += 2;
00788
00789 length = pos;
00790 pos += 2;
00791
00792
00793
00794
00795 *pos++ = level;
00796
00797 *pos++ = description;
00798
00799 WPA_PUT_BE16(length, pos - length - 2);
00800 *out_len = pos - alert;
00801
00802 return alert;
00803 }
00804