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/sha1.h"
00019 #include "crypto/tls.h"
00020 #include "tlsv1_common.h"
00021 #include "tlsv1_record.h"
00022 #include "tlsv1_client.h"
00023 #include "tlsv1_client_i.h"
00024
00025
00026
00027
00028
00029
00030 void tls_alert(struct tlsv1_client *conn, u8 level, u8 description)
00031 {
00032 conn->alert_level = level;
00033 conn->alert_description = description;
00034 }
00035
00036
00037 void tlsv1_client_free_dh(struct tlsv1_client *conn)
00038 {
00039 os_free(conn->dh_p);
00040 os_free(conn->dh_g);
00041 os_free(conn->dh_ys);
00042 conn->dh_p = conn->dh_g = conn->dh_ys = NULL;
00043 }
00044
00045
00046 int tls_derive_pre_master_secret(u8 *pre_master_secret)
00047 {
00048 WPA_PUT_BE16(pre_master_secret, TLS_VERSION);
00049 if (os_get_random(pre_master_secret + 2,
00050 TLS_PRE_MASTER_SECRET_LEN - 2))
00051 return -1;
00052 return 0;
00053 }
00054
00055
00056 int tls_derive_keys(struct tlsv1_client *conn,
00057 const u8 *pre_master_secret, size_t pre_master_secret_len)
00058 {
00059 u8 seed[2 * TLS_RANDOM_LEN];
00060 u8 key_block[TLS_MAX_KEY_BLOCK_LEN];
00061 u8 *pos;
00062 size_t key_block_len;
00063
00064 if (pre_master_secret) {
00065 wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: pre_master_secret",
00066 pre_master_secret, pre_master_secret_len);
00067 os_memcpy(seed, conn->client_random, TLS_RANDOM_LEN);
00068 os_memcpy(seed + TLS_RANDOM_LEN, conn->server_random,
00069 TLS_RANDOM_LEN);
00070 if (tls_prf(pre_master_secret, pre_master_secret_len,
00071 "master secret", seed, 2 * TLS_RANDOM_LEN,
00072 conn->master_secret, TLS_MASTER_SECRET_LEN)) {
00073 wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive "
00074 "master_secret");
00075 return -1;
00076 }
00077 wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: master_secret",
00078 conn->master_secret, TLS_MASTER_SECRET_LEN);
00079 }
00080
00081 os_memcpy(seed, conn->server_random, TLS_RANDOM_LEN);
00082 os_memcpy(seed + TLS_RANDOM_LEN, conn->client_random, TLS_RANDOM_LEN);
00083 key_block_len = 2 * (conn->rl.hash_size + conn->rl.key_material_len +
00084 conn->rl.iv_size);
00085 if (tls_prf(conn->master_secret, TLS_MASTER_SECRET_LEN,
00086 "key expansion", seed, 2 * TLS_RANDOM_LEN,
00087 key_block, key_block_len)) {
00088 wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive key_block");
00089 return -1;
00090 }
00091 wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: key_block",
00092 key_block, key_block_len);
00093
00094 pos = key_block;
00095
00096
00097 os_memcpy(conn->rl.write_mac_secret, pos, conn->rl.hash_size);
00098 pos += conn->rl.hash_size;
00099
00100 os_memcpy(conn->rl.read_mac_secret, pos, conn->rl.hash_size);
00101 pos += conn->rl.hash_size;
00102
00103
00104 os_memcpy(conn->rl.write_key, pos, conn->rl.key_material_len);
00105 pos += conn->rl.key_material_len;
00106
00107 os_memcpy(conn->rl.read_key, pos, conn->rl.key_material_len);
00108 pos += conn->rl.key_material_len;
00109
00110
00111 os_memcpy(conn->rl.write_iv, pos, conn->rl.iv_size);
00112 pos += conn->rl.iv_size;
00113
00114 os_memcpy(conn->rl.read_iv, pos, conn->rl.iv_size);
00115 pos += conn->rl.iv_size;
00116
00117 return 0;
00118 }
00119
00120
00131 u8 * tlsv1_client_handshake(struct tlsv1_client *conn,
00132 const u8 *in_data, size_t in_len,
00133 size_t *out_len, u8 **appl_data,
00134 size_t *appl_data_len)
00135 {
00136 const u8 *pos, *end;
00137 u8 *msg = NULL, *in_msg, *in_pos, *in_end, alert, ct;
00138 size_t in_msg_len;
00139 int no_appl_data;
00140
00141 if (conn->state == CLIENT_HELLO) {
00142 if (in_len)
00143 return NULL;
00144 return tls_send_client_hello(conn, out_len);
00145 }
00146
00147 if (in_data == NULL || in_len == 0)
00148 return NULL;
00149
00150 pos = in_data;
00151 end = in_data + in_len;
00152 in_msg = os_malloc(in_len);
00153 if (in_msg == NULL)
00154 return NULL;
00155
00156
00157 while (pos < end) {
00158 in_msg_len = in_len;
00159 if (tlsv1_record_receive(&conn->rl, pos, end - pos,
00160 in_msg, &in_msg_len, &alert)) {
00161 wpa_printf(MSG_DEBUG, "TLSv1: Processing received "
00162 "record failed");
00163 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);
00164 goto failed;
00165 }
00166 ct = pos[0];
00167
00168 in_pos = in_msg;
00169 in_end = in_msg + in_msg_len;
00170
00171
00172
00173 while (in_pos < in_end) {
00174 in_msg_len = in_end - in_pos;
00175 if (tlsv1_client_process_handshake(conn, ct, in_pos,
00176 &in_msg_len,
00177 appl_data,
00178 appl_data_len) < 0)
00179 goto failed;
00180 in_pos += in_msg_len;
00181 }
00182
00183 pos += TLS_RECORD_HEADER_LEN + WPA_GET_BE16(pos + 3);
00184 }
00185
00186 os_free(in_msg);
00187 in_msg = NULL;
00188
00189 no_appl_data = appl_data == NULL || *appl_data == NULL;
00190 msg = tlsv1_client_handshake_write(conn, out_len, no_appl_data);
00191
00192 failed:
00193 os_free(in_msg);
00194 if (conn->alert_level) {
00195 conn->state = FAILED;
00196 os_free(msg);
00197 msg = tlsv1_client_send_alert(conn, conn->alert_level,
00198 conn->alert_description,
00199 out_len);
00200 } else if (msg == NULL) {
00201 msg = os_zalloc(1);
00202 *out_len = 0;
00203 }
00204
00205 return msg;
00206 }
00207
00208
00221 int tlsv1_client_encrypt(struct tlsv1_client *conn,
00222 const u8 *in_data, size_t in_len,
00223 u8 *out_data, size_t out_len)
00224 {
00225 size_t rlen;
00226
00227 wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: Plaintext AppData",
00228 in_data, in_len);
00229
00230 os_memcpy(out_data + TLS_RECORD_HEADER_LEN, in_data, in_len);
00231
00232 if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_APPLICATION_DATA,
00233 out_data, out_len, in_len, &rlen) < 0) {
00234 wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
00235 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00236 TLS_ALERT_INTERNAL_ERROR);
00237 return -1;
00238 }
00239
00240 return rlen;
00241 }
00242
00243
00256 int tlsv1_client_decrypt(struct tlsv1_client *conn,
00257 const u8 *in_data, size_t in_len,
00258 u8 *out_data, size_t out_len)
00259 {
00260 const u8 *in_end, *pos;
00261 int res;
00262 u8 alert, *out_end, *out_pos;
00263 size_t olen;
00264
00265 pos = in_data;
00266 in_end = in_data + in_len;
00267 out_pos = out_data;
00268 out_end = out_data + out_len;
00269
00270 while (pos < in_end) {
00271 if (pos[0] != TLS_CONTENT_TYPE_APPLICATION_DATA) {
00272 wpa_printf(MSG_DEBUG, "TLSv1: Unexpected content type "
00273 "0x%x", pos[0]);
00274 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00275 TLS_ALERT_UNEXPECTED_MESSAGE);
00276 return -1;
00277 }
00278
00279 olen = out_end - out_pos;
00280 res = tlsv1_record_receive(&conn->rl, pos, in_end - pos,
00281 out_pos, &olen, &alert);
00282 if (res < 0) {
00283 wpa_printf(MSG_DEBUG, "TLSv1: Record layer processing "
00284 "failed");
00285 tls_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);
00286 return -1;
00287 }
00288 out_pos += olen;
00289 if (out_pos > out_end) {
00290 wpa_printf(MSG_DEBUG, "TLSv1: Buffer not large enough "
00291 "for processing the received record");
00292 tls_alert(conn, TLS_ALERT_LEVEL_FATAL,
00293 TLS_ALERT_INTERNAL_ERROR);
00294 return -1;
00295 }
00296
00297 pos += TLS_RECORD_HEADER_LEN + WPA_GET_BE16(pos + 3);
00298 }
00299
00300 return out_pos - out_data;
00301 }
00302
00303
00310 int tlsv1_client_global_init(void)
00311 {
00312 return crypto_global_init();
00313 }
00314
00315
00323 void tlsv1_client_global_deinit(void)
00324 {
00325 crypto_global_deinit();
00326 }
00327
00328
00333 struct tlsv1_client * tlsv1_client_init(void)
00334 {
00335 struct tlsv1_client *conn;
00336 size_t count;
00337 u16 *suites;
00338
00339 conn = os_zalloc(sizeof(*conn));
00340 if (conn == NULL)
00341 return NULL;
00342
00343 conn->state = CLIENT_HELLO;
00344
00345 if (tls_verify_hash_init(&conn->verify) < 0) {
00346 wpa_printf(MSG_DEBUG, "TLSv1: Failed to initialize verify "
00347 "hash");
00348 os_free(conn);
00349 return NULL;
00350 }
00351
00352 count = 0;
00353 suites = conn->cipher_suites;
00354 #ifndef CONFIG_CRYPTO_INTERNAL
00355 suites[count++] = TLS_RSA_WITH_AES_256_CBC_SHA;
00356 #endif
00357 suites[count++] = TLS_RSA_WITH_AES_128_CBC_SHA;
00358 suites[count++] = TLS_RSA_WITH_3DES_EDE_CBC_SHA;
00359 suites[count++] = TLS_RSA_WITH_RC4_128_SHA;
00360 suites[count++] = TLS_RSA_WITH_RC4_128_MD5;
00361 conn->num_cipher_suites = count;
00362
00363 return conn;
00364 }
00365
00366
00371 void tlsv1_client_deinit(struct tlsv1_client *conn)
00372 {
00373 crypto_public_key_free(conn->server_rsa_key);
00374 tlsv1_record_set_cipher_suite(&conn->rl, TLS_NULL_WITH_NULL_NULL);
00375 tlsv1_record_change_write_cipher(&conn->rl);
00376 tlsv1_record_change_read_cipher(&conn->rl);
00377 tls_verify_hash_free(&conn->verify);
00378 os_free(conn->client_hello_ext);
00379 tlsv1_client_free_dh(conn);
00380 tlsv1_cred_free(conn->cred);
00381 os_free(conn);
00382 }
00383
00384
00390 int tlsv1_client_established(struct tlsv1_client *conn)
00391 {
00392 return conn->state == ESTABLISHED;
00393 }
00394
00395
00406 int tlsv1_client_prf(struct tlsv1_client *conn, const char *label,
00407 int server_random_first, u8 *out, size_t out_len)
00408 {
00409 u8 seed[2 * TLS_RANDOM_LEN];
00410
00411 if (conn->state != ESTABLISHED)
00412 return -1;
00413
00414 if (server_random_first) {
00415 os_memcpy(seed, conn->server_random, TLS_RANDOM_LEN);
00416 os_memcpy(seed + TLS_RANDOM_LEN, conn->client_random,
00417 TLS_RANDOM_LEN);
00418 } else {
00419 os_memcpy(seed, conn->client_random, TLS_RANDOM_LEN);
00420 os_memcpy(seed + TLS_RANDOM_LEN, conn->server_random,
00421 TLS_RANDOM_LEN);
00422 }
00423
00424 return tls_prf(conn->master_secret, TLS_MASTER_SECRET_LEN,
00425 label, seed, 2 * TLS_RANDOM_LEN, out, out_len);
00426 }
00427
00428
00438 int tlsv1_client_get_cipher(struct tlsv1_client *conn, char *buf,
00439 size_t buflen)
00440 {
00441 char *cipher;
00442
00443 switch (conn->rl.cipher_suite) {
00444 case TLS_RSA_WITH_RC4_128_MD5:
00445 cipher = "RC4-MD5";
00446 break;
00447 case TLS_RSA_WITH_RC4_128_SHA:
00448 cipher = "RC4-SHA";
00449 break;
00450 case TLS_RSA_WITH_DES_CBC_SHA:
00451 cipher = "DES-CBC-SHA";
00452 break;
00453 case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
00454 cipher = "DES-CBC3-SHA";
00455 break;
00456 case TLS_DH_anon_WITH_AES_128_CBC_SHA:
00457 cipher = "ADH-AES-128-SHA";
00458 break;
00459 case TLS_RSA_WITH_AES_256_CBC_SHA:
00460 cipher = "AES-256-SHA";
00461 break;
00462 case TLS_RSA_WITH_AES_128_CBC_SHA:
00463 cipher = "AES-128-SHA";
00464 break;
00465 default:
00466 return -1;
00467 }
00468
00469 if (os_strlcpy(buf, cipher, buflen) >= buflen)
00470 return -1;
00471 return 0;
00472 }
00473
00474
00480 int tlsv1_client_shutdown(struct tlsv1_client *conn)
00481 {
00482 conn->state = CLIENT_HELLO;
00483
00484 if (tls_verify_hash_init(&conn->verify) < 0) {
00485 wpa_printf(MSG_DEBUG, "TLSv1: Failed to re-initialize verify "
00486 "hash");
00487 return -1;
00488 }
00489
00490 tlsv1_record_set_cipher_suite(&conn->rl, TLS_NULL_WITH_NULL_NULL);
00491 tlsv1_record_change_write_cipher(&conn->rl);
00492 tlsv1_record_change_read_cipher(&conn->rl);
00493
00494 conn->certificate_requested = 0;
00495 crypto_public_key_free(conn->server_rsa_key);
00496 conn->server_rsa_key = NULL;
00497 conn->session_resumed = 0;
00498
00499 return 0;
00500 }
00501
00502
00508 int tlsv1_client_resumed(struct tlsv1_client *conn)
00509 {
00510 return !!conn->session_resumed;
00511 }
00512
00513
00522 int tlsv1_client_hello_ext(struct tlsv1_client *conn, int ext_type,
00523 const u8 *data, size_t data_len)
00524 {
00525 u8 *pos;
00526
00527 conn->session_ticket_included = 0;
00528 os_free(conn->client_hello_ext);
00529 conn->client_hello_ext = NULL;
00530 conn->client_hello_ext_len = 0;
00531
00532 if (data == NULL || data_len == 0)
00533 return 0;
00534
00535 pos = conn->client_hello_ext = os_malloc(6 + data_len);
00536 if (pos == NULL)
00537 return -1;
00538
00539 WPA_PUT_BE16(pos, 4 + data_len);
00540 pos += 2;
00541 WPA_PUT_BE16(pos, ext_type);
00542 pos += 2;
00543 WPA_PUT_BE16(pos, data_len);
00544 pos += 2;
00545 os_memcpy(pos, data, data_len);
00546 conn->client_hello_ext_len = 6 + data_len;
00547
00548 if (ext_type == TLS_EXT_PAC_OPAQUE) {
00549 conn->session_ticket_included = 1;
00550 wpa_printf(MSG_DEBUG, "TLSv1: Using session ticket");
00551 }
00552
00553 return 0;
00554 }
00555
00556
00563 int tlsv1_client_get_keys(struct tlsv1_client *conn, struct tls_keys *keys)
00564 {
00565 os_memset(keys, 0, sizeof(*keys));
00566 if (conn->state == CLIENT_HELLO)
00567 return -1;
00568
00569 keys->client_random = conn->client_random;
00570 keys->client_random_len = TLS_RANDOM_LEN;
00571
00572 if (conn->state != SERVER_HELLO) {
00573 keys->server_random = conn->server_random;
00574 keys->server_random_len = TLS_RANDOM_LEN;
00575 keys->master_key = conn->master_secret;
00576 keys->master_key_len = TLS_MASTER_SECRET_LEN;
00577 }
00578
00579 return 0;
00580 }
00581
00582
00589 int tlsv1_client_get_keyblock_size(struct tlsv1_client *conn)
00590 {
00591 if (conn->state == CLIENT_HELLO || conn->state == SERVER_HELLO)
00592 return -1;
00593
00594 return 2 * (conn->rl.hash_size + conn->rl.key_material_len +
00595 conn->rl.iv_size);
00596 }
00597
00598
00606 int tlsv1_client_set_cipher_list(struct tlsv1_client *conn, u8 *ciphers)
00607 {
00608 size_t count;
00609 u16 *suites;
00610
00611
00612 if (ciphers[0] == TLS_CIPHER_ANON_DH_AES128_SHA) {
00613 count = 0;
00614 suites = conn->cipher_suites;
00615 #ifndef CONFIG_CRYPTO_INTERNAL
00616 suites[count++] = TLS_DH_anon_WITH_AES_256_CBC_SHA;
00617 #endif
00618 suites[count++] = TLS_DH_anon_WITH_AES_128_CBC_SHA;
00619 suites[count++] = TLS_DH_anon_WITH_3DES_EDE_CBC_SHA;
00620 suites[count++] = TLS_DH_anon_WITH_RC4_128_MD5;
00621 suites[count++] = TLS_DH_anon_WITH_DES_CBC_SHA;
00622
00623
00624
00625
00626
00627
00628
00629
00630
00631
00632 suites[count++] = TLS_DH_anon_WITH_AES_128_CBC_SHA;
00633 conn->num_cipher_suites = count;
00634 }
00635
00636 return 0;
00637 }
00638
00639
00650 int tlsv1_client_set_cred(struct tlsv1_client *conn,
00651 struct tlsv1_credentials *cred)
00652 {
00653 tlsv1_cred_free(conn->cred);
00654 conn->cred = cred;
00655 return 0;
00656 }
00657
00658
00659 void tlsv1_client_set_session_ticket_cb(struct tlsv1_client *conn,
00660 tlsv1_client_session_ticket_cb cb,
00661 void *ctx)
00662 {
00663 wpa_printf(MSG_DEBUG, "TLSv1: SessionTicket callback set %p (ctx %p)",
00664 cb, ctx);
00665 conn->session_ticket_cb = cb;
00666 conn->session_ticket_cb_ctx = ctx;
00667 }