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