tlsv1_server.c

Go to the documentation of this file.
00001 
00016 #include "includes.h"
00017 
00018 #include "common.h"
00019 #include "sha1.h"
00020 #include "tls.h"
00021 #include "tlsv1_common.h"
00022 #include "tlsv1_record.h"
00023 #include "tlsv1_server.h"
00024 #include "tlsv1_server_i.h"
00025 
00026 /* TODO:
00027  * Support for a message fragmented across several records (RFC 2246, 6.2.1)
00028  */
00029 
00030 
00031 void tlsv1_server_alert(struct tlsv1_server *conn, u8 level, u8 description)
00032 {
00033         conn->alert_level = level;
00034         conn->alert_description = description;
00035 }
00036 
00037 
00038 int tlsv1_server_derive_keys(struct tlsv1_server *conn,
00039                              const u8 *pre_master_secret,
00040                              size_t pre_master_secret_len)
00041 {
00042         u8 seed[2 * TLS_RANDOM_LEN];
00043         u8 key_block[TLS_MAX_KEY_BLOCK_LEN];
00044         u8 *pos;
00045         size_t key_block_len;
00046 
00047         if (pre_master_secret) {
00048                 wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: pre_master_secret",
00049                                 pre_master_secret, pre_master_secret_len);
00050                 os_memcpy(seed, conn->client_random, TLS_RANDOM_LEN);
00051                 os_memcpy(seed + TLS_RANDOM_LEN, conn->server_random,
00052                           TLS_RANDOM_LEN);
00053                 if (tls_prf(pre_master_secret, pre_master_secret_len,
00054                             "master secret", seed, 2 * TLS_RANDOM_LEN,
00055                             conn->master_secret, TLS_MASTER_SECRET_LEN)) {
00056                         wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive "
00057                                    "master_secret");
00058                         return -1;
00059                 }
00060                 wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: master_secret",
00061                                 conn->master_secret, TLS_MASTER_SECRET_LEN);
00062         }
00063 
00064         os_memcpy(seed, conn->server_random, TLS_RANDOM_LEN);
00065         os_memcpy(seed + TLS_RANDOM_LEN, conn->client_random, TLS_RANDOM_LEN);
00066         key_block_len = 2 * (conn->rl.hash_size + conn->rl.key_material_len +
00067                              conn->rl.iv_size);
00068         if (tls_prf(conn->master_secret, TLS_MASTER_SECRET_LEN,
00069                     "key expansion", seed, 2 * TLS_RANDOM_LEN,
00070                     key_block, key_block_len)) {
00071                 wpa_printf(MSG_DEBUG, "TLSv1: Failed to derive key_block");
00072                 return -1;
00073         }
00074         wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: key_block",
00075                         key_block, key_block_len);
00076 
00077         pos = key_block;
00078 
00079         /* client_write_MAC_secret */
00080         os_memcpy(conn->rl.read_mac_secret, pos, conn->rl.hash_size);
00081         pos += conn->rl.hash_size;
00082         /* server_write_MAC_secret */
00083         os_memcpy(conn->rl.write_mac_secret, pos, conn->rl.hash_size);
00084         pos += conn->rl.hash_size;
00085 
00086         /* client_write_key */
00087         os_memcpy(conn->rl.read_key, pos, conn->rl.key_material_len);
00088         pos += conn->rl.key_material_len;
00089         /* server_write_key */
00090         os_memcpy(conn->rl.write_key, pos, conn->rl.key_material_len);
00091         pos += conn->rl.key_material_len;
00092 
00093         /* client_write_IV */
00094         os_memcpy(conn->rl.read_iv, pos, conn->rl.iv_size);
00095         pos += conn->rl.iv_size;
00096         /* server_write_IV */
00097         os_memcpy(conn->rl.write_iv, pos, conn->rl.iv_size);
00098         pos += conn->rl.iv_size;
00099 
00100         return 0;
00101 }
00102 
00103 
00113 u8 * tlsv1_server_handshake(struct tlsv1_server *conn,
00114                             const u8 *in_data, size_t in_len,
00115                             size_t *out_len)
00116 {
00117         const u8 *pos, *end;
00118         u8 *msg = NULL, *in_msg, *in_pos, *in_end, alert, ct;
00119         size_t in_msg_len;
00120 
00121         if (in_data == NULL || in_len == 0) {
00122                 wpa_printf(MSG_DEBUG, "TLSv1: No input data to server");
00123                 return NULL;
00124         }
00125 
00126         pos = in_data;
00127         end = in_data + in_len;
00128         in_msg = os_malloc(in_len);
00129         if (in_msg == NULL)
00130                 return NULL;
00131 
00132         /* Each received packet may include multiple records */
00133         while (pos < end) {
00134                 in_msg_len = in_len;
00135                 if (tlsv1_record_receive(&conn->rl, pos, end - pos,
00136                                          in_msg, &in_msg_len, &alert)) {
00137                         wpa_printf(MSG_DEBUG, "TLSv1: Processing received "
00138                                    "record failed");
00139                         tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);
00140                         goto failed;
00141                 }
00142                 ct = pos[0];
00143 
00144                 in_pos = in_msg;
00145                 in_end = in_msg + in_msg_len;
00146 
00147                 /* Each received record may include multiple messages of the
00148                  * same ContentType. */
00149                 while (in_pos < in_end) {
00150                         in_msg_len = in_end - in_pos;
00151                         if (tlsv1_server_process_handshake(conn, ct, in_pos,
00152                                                            &in_msg_len) < 0)
00153                                 goto failed;
00154                         in_pos += in_msg_len;
00155                 }
00156 
00157                 pos += TLS_RECORD_HEADER_LEN + WPA_GET_BE16(pos + 3);
00158         }
00159 
00160         os_free(in_msg);
00161         in_msg = NULL;
00162 
00163         msg = tlsv1_server_handshake_write(conn, out_len);
00164 
00165 failed:
00166         os_free(in_msg);
00167         if (conn->alert_level) {
00168                 if (conn->state == FAILED) {
00169                         /* Avoid alert loops */
00170                         wpa_printf(MSG_DEBUG, "TLSv1: Drop alert loop");
00171                         os_free(msg);
00172                         return NULL;
00173                 }
00174                 conn->state = FAILED;
00175                 os_free(msg);
00176                 msg = tlsv1_server_send_alert(conn, conn->alert_level,
00177                                               conn->alert_description,
00178                                               out_len);
00179         }
00180 
00181         return msg;
00182 }
00183 
00184 
00198 int tlsv1_server_encrypt(struct tlsv1_server *conn,
00199                          const u8 *in_data, size_t in_len,
00200                          u8 *out_data, size_t out_len)
00201 {
00202         size_t rlen;
00203 
00204         wpa_hexdump_key(MSG_MSGDUMP, "TLSv1: Plaintext AppData",
00205                         in_data, in_len);
00206 
00207         os_memcpy(out_data + TLS_RECORD_HEADER_LEN, in_data, in_len);
00208 
00209         if (tlsv1_record_send(&conn->rl, TLS_CONTENT_TYPE_APPLICATION_DATA,
00210                               out_data, out_len, in_len, &rlen) < 0) {
00211                 wpa_printf(MSG_DEBUG, "TLSv1: Failed to create a record");
00212                 tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00213                                    TLS_ALERT_INTERNAL_ERROR);
00214                 return -1;
00215         }
00216 
00217         return rlen;
00218 }
00219 
00220 
00234 int tlsv1_server_decrypt(struct tlsv1_server *conn,
00235                          const u8 *in_data, size_t in_len,
00236                          u8 *out_data, size_t out_len)
00237 {
00238         const u8 *in_end, *pos;
00239         int res;
00240         u8 alert, *out_end, *out_pos;
00241         size_t olen;
00242 
00243         pos = in_data;
00244         in_end = in_data + in_len;
00245         out_pos = out_data;
00246         out_end = out_data + out_len;
00247 
00248         while (pos < in_end) {
00249                 if (pos[0] != TLS_CONTENT_TYPE_APPLICATION_DATA) {
00250                         wpa_printf(MSG_DEBUG, "TLSv1: Unexpected content type "
00251                                    "0x%x", pos[0]);
00252                         tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00253                                            TLS_ALERT_UNEXPECTED_MESSAGE);
00254                         return -1;
00255                 }
00256 
00257                 olen = out_end - out_pos;
00258                 res = tlsv1_record_receive(&conn->rl, pos, in_end - pos,
00259                                            out_pos, &olen, &alert);
00260                 if (res < 0) {
00261                         wpa_printf(MSG_DEBUG, "TLSv1: Record layer processing "
00262                                    "failed");
00263                         tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL, alert);
00264                         return -1;
00265                 }
00266                 out_pos += olen;
00267                 if (out_pos > out_end) {
00268                         wpa_printf(MSG_DEBUG, "TLSv1: Buffer not large enough "
00269                                    "for processing the received record");
00270                         tlsv1_server_alert(conn, TLS_ALERT_LEVEL_FATAL,
00271                                            TLS_ALERT_INTERNAL_ERROR);
00272                         return -1;
00273                 }
00274 
00275                 pos += TLS_RECORD_HEADER_LEN + WPA_GET_BE16(pos + 3);
00276         }
00277 
00278         return out_pos - out_data;
00279 }
00280 
00281 
00289 int tlsv1_server_global_init(void)
00290 {
00291         return crypto_global_init();
00292 }
00293 
00294 
00303 void tlsv1_server_global_deinit(void)
00304 {
00305         crypto_global_deinit();
00306 }
00307 
00308 
00315 struct tlsv1_server * tlsv1_server_init(struct tlsv1_credentials *cred)
00316 {
00317         struct tlsv1_server *conn;
00318         size_t count;
00319         u16 *suites;
00320 
00321         conn = os_zalloc(sizeof(*conn));
00322         if (conn == NULL)
00323                 return NULL;
00324 
00325         conn->cred = cred;
00326 
00327         conn->state = CLIENT_HELLO;
00328 
00329         if (tls_verify_hash_init(&conn->verify) < 0) {
00330                 wpa_printf(MSG_DEBUG, "TLSv1: Failed to initialize verify "
00331                            "hash");
00332                 os_free(conn);
00333                 return NULL;
00334         }
00335 
00336         count = 0;
00337         suites = conn->cipher_suites;
00338 #ifndef CONFIG_CRYPTO_INTERNAL
00339         suites[count++] = TLS_RSA_WITH_AES_256_CBC_SHA;
00340 #endif /* CONFIG_CRYPTO_INTERNAL */
00341         suites[count++] = TLS_RSA_WITH_AES_128_CBC_SHA;
00342         suites[count++] = TLS_RSA_WITH_3DES_EDE_CBC_SHA;
00343         suites[count++] = TLS_RSA_WITH_RC4_128_SHA;
00344         suites[count++] = TLS_RSA_WITH_RC4_128_MD5;
00345         conn->num_cipher_suites = count;
00346 
00347         return conn;
00348 }
00349 
00350 
00351 static void tlsv1_server_clear_data(struct tlsv1_server *conn)
00352 {
00353         tlsv1_record_set_cipher_suite(&conn->rl, TLS_NULL_WITH_NULL_NULL);
00354         tlsv1_record_change_write_cipher(&conn->rl);
00355         tlsv1_record_change_read_cipher(&conn->rl);
00356         tls_verify_hash_free(&conn->verify);
00357 
00358         crypto_public_key_free(conn->client_rsa_key);
00359         conn->client_rsa_key = NULL;
00360 
00361         os_free(conn->session_ticket);
00362         conn->session_ticket = NULL;
00363         conn->session_ticket_len = 0;
00364         conn->use_session_ticket = 0;
00365 
00366         os_free(conn->dh_secret);
00367         conn->dh_secret = NULL;
00368         conn->dh_secret_len = 0;
00369 }
00370 
00371 
00377 void tlsv1_server_deinit(struct tlsv1_server *conn)
00378 {
00379         tlsv1_server_clear_data(conn);
00380         os_free(conn);
00381 }
00382 
00383 
00390 int tlsv1_server_established(struct tlsv1_server *conn)
00391 {
00392         return conn->state == ESTABLISHED;
00393 }
00394 
00395 
00407 int tlsv1_server_prf(struct tlsv1_server *conn, const char *label,
00408                      int server_random_first, u8 *out, size_t out_len)
00409 {
00410         u8 seed[2 * TLS_RANDOM_LEN];
00411 
00412         if (conn->state != ESTABLISHED)
00413                 return -1;
00414 
00415         if (server_random_first) {
00416                 os_memcpy(seed, conn->server_random, TLS_RANDOM_LEN);
00417                 os_memcpy(seed + TLS_RANDOM_LEN, conn->client_random,
00418                           TLS_RANDOM_LEN);
00419         } else {
00420                 os_memcpy(seed, conn->client_random, TLS_RANDOM_LEN);
00421                 os_memcpy(seed + TLS_RANDOM_LEN, conn->server_random,
00422                           TLS_RANDOM_LEN);
00423         }
00424 
00425         return tls_prf(conn->master_secret, TLS_MASTER_SECRET_LEN,
00426                        label, seed, 2 * TLS_RANDOM_LEN, out, out_len);
00427 }
00428 
00429 
00440 int tlsv1_server_get_cipher(struct tlsv1_server *conn, char *buf,
00441                             size_t buflen)
00442 {
00443         char *cipher;
00444 
00445         switch (conn->rl.cipher_suite) {
00446         case TLS_RSA_WITH_RC4_128_MD5:
00447                 cipher = "RC4-MD5";
00448                 break;
00449         case TLS_RSA_WITH_RC4_128_SHA:
00450                 cipher = "RC4-SHA";
00451                 break;
00452         case TLS_RSA_WITH_DES_CBC_SHA:
00453                 cipher = "DES-CBC-SHA";
00454                 break;
00455         case TLS_RSA_WITH_3DES_EDE_CBC_SHA:
00456                 cipher = "DES-CBC3-SHA";
00457                 break;
00458         case TLS_DH_anon_WITH_AES_128_CBC_SHA:
00459                 cipher = "ADH-AES-128-SHA";
00460                 break;
00461         case TLS_RSA_WITH_AES_256_CBC_SHA:
00462                 cipher = "AES-256-SHA";
00463                 break;
00464         case TLS_RSA_WITH_AES_128_CBC_SHA:
00465                 cipher = "AES-128-SHA";
00466                 break;
00467         default:
00468                 return -1;
00469         }
00470 
00471         if (os_strlcpy(buf, cipher, buflen) >= buflen)
00472                 return -1;
00473         return 0;
00474 }
00475 
00476 
00483 int tlsv1_server_shutdown(struct tlsv1_server *conn)
00484 {
00485         conn->state = CLIENT_HELLO;
00486 
00487         if (tls_verify_hash_init(&conn->verify) < 0) {
00488                 wpa_printf(MSG_DEBUG, "TLSv1: Failed to re-initialize verify "
00489                            "hash");
00490                 return -1;
00491         }
00492 
00493         tlsv1_server_clear_data(conn);
00494 
00495         return 0;
00496 }
00497 
00498 
00505 int tlsv1_server_resumed(struct tlsv1_server *conn)
00506 {
00507         return 0;
00508 }
00509 
00510 
00518 int tlsv1_server_get_keys(struct tlsv1_server *conn, struct tls_keys *keys)
00519 {
00520         os_memset(keys, 0, sizeof(*keys));
00521         if (conn->state == CLIENT_HELLO)
00522                 return -1;
00523 
00524         keys->client_random = conn->client_random;
00525         keys->client_random_len = TLS_RANDOM_LEN;
00526 
00527         if (conn->state != SERVER_HELLO) {
00528                 keys->server_random = conn->server_random;
00529                 keys->server_random_len = TLS_RANDOM_LEN;
00530                 keys->master_key = conn->master_secret;
00531                 keys->master_key_len = TLS_MASTER_SECRET_LEN;
00532         }
00533 
00534         return 0;
00535 }
00536 
00537 
00545 int tlsv1_server_get_keyblock_size(struct tlsv1_server *conn)
00546 {
00547         if (conn->state == CLIENT_HELLO || conn->state == SERVER_HELLO)
00548                 return -1;
00549 
00550         return 2 * (conn->rl.hash_size + conn->rl.key_material_len +
00551                     conn->rl.iv_size);
00552 }
00553 
00554 
00563 int tlsv1_server_set_cipher_list(struct tlsv1_server *conn, u8 *ciphers)
00564 {
00565 #ifdef EAP_SERVER_FAST
00566         size_t count;
00567         u16 *suites;
00568 
00569         /* TODO: implement proper configuration of cipher suites */
00570         if (ciphers[0] == TLS_CIPHER_ANON_DH_AES128_SHA) {
00571                 count = 0;
00572                 suites = conn->cipher_suites;
00573 #ifndef CONFIG_CRYPTO_INTERNAL
00574                 suites[count++] = TLS_RSA_WITH_AES_256_CBC_SHA;
00575 #endif /* CONFIG_CRYPTO_INTERNAL */
00576                 suites[count++] = TLS_RSA_WITH_AES_128_CBC_SHA;
00577                 suites[count++] = TLS_RSA_WITH_3DES_EDE_CBC_SHA;
00578                 suites[count++] = TLS_RSA_WITH_RC4_128_SHA;
00579                 suites[count++] = TLS_RSA_WITH_RC4_128_MD5;
00580 #ifndef CONFIG_CRYPTO_INTERNAL
00581                 suites[count++] = TLS_DH_anon_WITH_AES_256_CBC_SHA;
00582 #endif /* CONFIG_CRYPTO_INTERNAL */
00583                 suites[count++] = TLS_DH_anon_WITH_AES_128_CBC_SHA;
00584                 suites[count++] = TLS_DH_anon_WITH_3DES_EDE_CBC_SHA;
00585                 suites[count++] = TLS_DH_anon_WITH_RC4_128_MD5;
00586                 suites[count++] = TLS_DH_anon_WITH_DES_CBC_SHA;
00587                 conn->num_cipher_suites = count;
00588         }
00589 
00590         return 0;
00591 #else /* EAP_SERVER_FAST */
00592         return -1;
00593 #endif /* EAP_SERVER_FAST */
00594 }
00595 
00596 
00597 int tlsv1_server_set_verify(struct tlsv1_server *conn, int verify_peer)
00598 {
00599         conn->verify_peer = verify_peer;
00600         return 0;
00601 }
00602 
00603 
00604 void tlsv1_server_set_session_ticket_cb(struct tlsv1_server *conn,
00605                                         tlsv1_server_session_ticket_cb cb,
00606                                         void *ctx)
00607 {
00608         wpa_printf(MSG_DEBUG, "TLSv1: SessionTicket callback set %p (ctx %p)",
00609                    cb, ctx);
00610         conn->session_ticket_cb = cb;
00611         conn->session_ticket_cb_ctx = ctx;
00612 }
00613 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines

Generated on Sat Nov 21 23:16:53 2009 for hostapd by  doxygen 1.6.1