$search
00001 /* 00002 * TLSv1 client (RFC 2246) 00003 * Copyright (c) 2006-2007, Jouni Malinen <j@w1.fi> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License version 2 as 00007 * published by the Free Software Foundation. 00008 * 00009 * Alternatively, this software may be distributed under the terms of BSD 00010 * license. 00011 * 00012 * See README and COPYING for more details. 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 /* TODO: 00026 * Support for a message fragmented across several records (RFC 2246, 6.2.1) 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 /* client_write_MAC_secret */ 00097 os_memcpy(conn->rl.write_mac_secret, pos, conn->rl.hash_size); 00098 pos += conn->rl.hash_size; 00099 /* server_write_MAC_secret */ 00100 os_memcpy(conn->rl.read_mac_secret, pos, conn->rl.hash_size); 00101 pos += conn->rl.hash_size; 00102 00103 /* client_write_key */ 00104 os_memcpy(conn->rl.write_key, pos, conn->rl.key_material_len); 00105 pos += conn->rl.key_material_len; 00106 /* server_write_key */ 00107 os_memcpy(conn->rl.read_key, pos, conn->rl.key_material_len); 00108 pos += conn->rl.key_material_len; 00109 00110 /* client_write_IV */ 00111 os_memcpy(conn->rl.write_iv, pos, conn->rl.iv_size); 00112 pos += conn->rl.iv_size; 00113 /* server_write_IV */ 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 /* Each received packet may include multiple records */ 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 /* Each received record may include multiple messages of the 00172 * same ContentType. */ 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 /* CONFIG_CRYPTO_INTERNAL */ 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 /* TODO: implement proper configuration of cipher suites */ 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 /* CONFIG_CRYPTO_INTERNAL */ 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 * Cisco AP (at least 350 and 1200 series) local authentication 00625 * server does not know how to search cipher suites from the 00626 * list and seem to require that the last entry in the list is 00627 * the one that it wants to use. However, TLS specification 00628 * requires the list to be in the client preference order. As a 00629 * workaround, add anon-DH AES-128-SHA1 again at the end of the 00630 * list to allow the Cisco code to find it. 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 }