18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-TLS/PEAP/TTLS/FAST server common functions 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2004-2009, Jouni Malinen <j@w1.fi> 48d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 5c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * This software may be distributed under the terms of the BSD license. 6c5ec7f57ead87efa365800228aa0b09a12d9e6c4Dmitry Shmidt * See README for more details. 78d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 88d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 98d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "includes.h" 108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "common.h" 128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/sha1.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "crypto/tls.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_i.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_tls_common.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_server_tls_free_in_buf(struct eap_ssl_data *data); 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstruct wpabuf * eap_tls_msg_alloc(EapType type, size_t payload_len, 2261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 code, u8 identifier) 2361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 2461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (type == EAP_UNAUTH_TLS_TYPE) 2561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return eap_msg_alloc(EAP_VENDOR_UNAUTH_TLS, 2661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt EAP_VENDOR_TYPE_UNAUTH_TLS, payload_len, 2761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt code, identifier); 28f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt else if (type == EAP_WFA_UNAUTH_TLS_TYPE) 29f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return eap_msg_alloc(EAP_VENDOR_WFA_NEW, 30f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt EAP_VENDOR_WFA_UNAUTH_TLS, payload_len, 31f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt code, identifier); 3261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return eap_msg_alloc(EAP_VENDOR_IETF, type, payload_len, code, 3361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt identifier); 3461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 3561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 3661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 37818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_TLS_INTERNAL 38818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidtstatic void eap_server_tls_log_cb(void *ctx, const char *msg) 39818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt{ 40818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt struct eap_sm *sm = ctx; 41818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt eap_log_msg(sm, "TLS: %s", msg); 42818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt} 43818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_TLS_INTERNAL */ 44818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 45818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_server_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data, 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int verify_peer) 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4901904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt if (sm->ssl_ctx == NULL) { 5001904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt wpa_printf(MSG_ERROR, "TLS context not initialized - cannot use TLS-based EAP method"); 5101904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt return -1; 5201904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt } 5301904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->eap = sm; 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->phase2 = sm->init_phase2; 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->conn = tls_connection_init(sm->ssl_ctx); 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->conn == NULL) { 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "SSL: Failed to initialize new TLS " 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "connection"); 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 64818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_TLS_INTERNAL 65818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tls_connection_set_log_cb(data->conn, eap_server_tls_log_cb, sm); 66818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_TESTING_OPTIONS 67818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tls_connection_set_test_flags(data->conn, sm->tls_test_flags); 68818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_TESTING_OPTIONS */ 69818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_TLS_INTERNAL */ 70818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_connection_set_verify(sm->ssl_ctx, data->conn, verify_peer)) { 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "SSL: Failed to configure verification " 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "of TLS peer certificate"); 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_connection_deinit(sm->ssl_ctx, data->conn); 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->conn = NULL; 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_out_limit = sm->fragment_size > 0 ? sm->fragment_size : 1398; 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->phase2) { 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Limit the fragment size in the inner TLS authentication 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * since the outer authentication with EAP-PEAP does not yet 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * support fragmentation */ 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_out_limit > 100) 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_out_limit -= 100; 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_server_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data) 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_connection_deinit(sm->ssl_ctx, data->conn); 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_server_tls_free_in_buf(data); 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(data->tls_out); 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_out = NULL; 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtu8 * eap_server_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data, 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *label, size_t len) 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_keys keys; 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *rnd = NULL, *out; 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out = os_malloc(len); 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (out == NULL) 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_connection_prf(sm->ssl_ctx, data->conn, label, 0, out, len) == 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return out; 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_connection_get_keys(sm->ssl_ctx, data->conn, &keys)) 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (keys.client_random == NULL || keys.server_random == NULL || 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keys.master_key == NULL) 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt rnd = os_malloc(keys.client_random_len + keys.server_random_len); 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (rnd == NULL) 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(rnd, keys.client_random, keys.client_random_len); 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(rnd + keys.client_random_len, keys.server_random, 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt keys.server_random_len); 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1281f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt if (tls_prf_sha1_md5(keys.master_key, keys.master_key_len, 1291f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt label, rnd, keys.client_random_len + 1301f69aa52ea2e0a73ac502565df8c666ee49cab6aDmitry Shmidt keys.server_random_len, out, len)) 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto fail; 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(rnd); 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return out; 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtfail: 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(out); 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(rnd); 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * eap_server_tls_build_msg(struct eap_ssl_data *data, 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int eap_type, int version, u8 id) 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *req; 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 flags; 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t send_len, plen; 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Generating Request"); 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_out == NULL) { 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "SSL: tls_out NULL in %s", __func__); 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt flags = version; 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt send_len = wpabuf_len(data->tls_out) - data->tls_out_pos; 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (1 + send_len > data->tls_out_limit) { 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt send_len = data->tls_out_limit - 1; 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt flags |= EAP_TLS_FLAGS_MORE_FRAGMENTS; 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_out_pos == 0) { 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt flags |= EAP_TLS_FLAGS_LENGTH_INCLUDED; 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt send_len -= 4; 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt plen = 1 + send_len; 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt plen += 4; 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 17161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt req = eap_tls_msg_alloc(eap_type, plen, EAP_CODE_REQUEST, id); 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req == NULL) 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(req, flags); /* Flags */ 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_be32(req, wpabuf_len(data->tls_out)); 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(req, wpabuf_head_u8(data->tls_out) + data->tls_out_pos, 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt send_len); 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_out_pos += send_len; 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_out_pos == wpabuf_len(data->tls_out)) { 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Sending out %lu bytes " 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(message sent completely)", 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) send_len); 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(data->tls_out); 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_out = NULL; 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_out_pos = 0; 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->state = MSG; 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Sending out %lu bytes " 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(%lu more to send)", (unsigned long) send_len, 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) wpabuf_len(data->tls_out) - 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_out_pos); 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->state = WAIT_FRAG_ACK; 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return req; 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * eap_server_tls_build_ack(u8 id, int eap_type, int version) 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *req; 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 20761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt req = eap_tls_msg_alloc(eap_type, 1, EAP_CODE_REQUEST, id); 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req == NULL) 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Building ACK"); 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(req, version); /* Flags */ 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return req; 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_server_tls_process_cont(struct eap_ssl_data *data, 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *buf, size_t len) 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Process continuation of a pending message */ 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > wpabuf_tailroom(data->tls_in)) { 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Fragment overflow"); 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(data->tls_in, buf, len); 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Received %lu bytes, waiting for %lu " 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "bytes more", (unsigned long) len, 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) wpabuf_tailroom(data->tls_in)); 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_server_tls_process_fragment(struct eap_ssl_data *data, 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 flags, u32 message_length, 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *buf, size_t len) 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Process a fragment that is not the last one of the message */ 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_in == NULL && !(flags & EAP_TLS_FLAGS_LENGTH_INCLUDED)) { 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: No Message Length field in a " 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "fragmented packet"); 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_in == NULL) { 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* First fragment of the message */ 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Limit length to avoid rogue peers from causing large 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * memory allocations. */ 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (message_length > 65536) { 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "SSL: Too long TLS fragment (size" 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " over 64 kB)"); 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 256d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (len > message_length) { 257d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_printf(MSG_INFO, "SSL: Too much data (%d bytes) in " 258d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "first fragment of frame (TLS Message " 259d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "Length %d bytes)", 260d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt (int) len, (int) message_length); 261d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 262d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 263d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_in = wpabuf_alloc(message_length); 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_in == NULL) { 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: No memory for message"); 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(data->tls_in, buf, len); 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Received %lu bytes in first " 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "fragment, waiting for %lu bytes more", 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) wpabuf_tailroom(data->tls_in)); 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_server_tls_phase1(struct eap_sm *sm, struct eap_ssl_data *data) 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_out) { 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* This should not happen.. */ 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "SSL: pending tls_out data when " 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "processing new message"); 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(data->tls_out); 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_ASSERT(data->tls_out == NULL); 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_out = tls_connection_server_handshake(sm->ssl_ctx, 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->conn, 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_in, NULL); 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_out == NULL) { 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "SSL: TLS processing failed"); 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_connection_get_failed(sm->ssl_ctx, data->conn)) { 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TLS processing has failed - return error */ 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Failed - tls_out available to " 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "report error"); 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_server_tls_reassemble(struct eap_ssl_data *data, u8 flags, 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 **pos, size_t *left) 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int tls_msg_len = 0; 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *end = *pos + *left; 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) { 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*left < 4) { 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "SSL: Short frame with TLS " 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length"); 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_msg_len = WPA_GET_BE32(*pos); 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: TLS Message Length: %d", 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_msg_len); 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos += 4; 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *left -= 4; 325d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 326d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (*left > tls_msg_len) { 327d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_printf(MSG_INFO, "SSL: TLS Message Length (%d " 328d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "bytes) smaller than this fragment (%d " 329d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "bytes)", (int) tls_msg_len, (int) *left); 330d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 331d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Received packet: Flags 0x%x " 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Message Length %u", flags, tls_msg_len); 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->state == WAIT_FRAG_ACK) { 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*left != 0) { 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Unexpected payload in " 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WAIT_FRAG_ACK state"); 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Fragment acknowledged"); 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_in && 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_server_tls_process_cont(data, *pos, end - *pos) < 0) 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (flags & EAP_TLS_FLAGS_MORE_FRAGMENTS) { 3528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_server_tls_process_fragment(data, flags, tls_msg_len, 3538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos, end - *pos) < 0) 3548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->state = FRAG_ACK; 3578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->state == FRAG_ACK) { 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: All fragments received"); 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->state = MSG; 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_in == NULL) { 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Wrap unfragmented messages as wpabuf without extra copy */ 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_set(&data->tmpbuf, *pos, end - *pos); 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_in = &data->tmpbuf; 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_server_tls_free_in_buf(struct eap_ssl_data *data) 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_in != &data->tmpbuf) 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(data->tls_in); 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_in = NULL; 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * eap_server_tls_encrypt(struct eap_sm *sm, 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_ssl_data *data, 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *plain) 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = tls_connection_encrypt(sm->ssl_ctx, data->conn, 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt plain); 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) { 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "SSL: Failed to encrypt Phase 2 data"); 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_server_tls_process(struct eap_sm *sm, struct eap_ssl_data *data, 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *respData, void *priv, int eap_type, 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int (*proc_version)(struct eap_sm *sm, void *priv, 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int peer_version), 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void (*proc_msg)(struct eap_sm *sm, void *priv, 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *respData)) 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos; 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 flags; 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left; 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret, res = 0; 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 41261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (eap_type == EAP_UNAUTH_TLS_TYPE) 41361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos = eap_hdr_validate(EAP_VENDOR_UNAUTH_TLS, 41461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt EAP_VENDOR_TYPE_UNAUTH_TLS, respData, 41561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt &left); 416f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt else if (eap_type == EAP_WFA_UNAUTH_TLS_TYPE) 417f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt pos = eap_hdr_validate(EAP_VENDOR_WFA_NEW, 418f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt EAP_VENDOR_WFA_UNAUTH_TLS, respData, 419f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt &left); 42061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt else 42161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos = eap_hdr_validate(EAP_VENDOR_IETF, eap_type, respData, 42261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt &left); 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL || left < 1) 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* Should not happen - frame already validated */ 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt flags = *pos++; 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left--; 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Received packet(len=%lu) - Flags 0x%02x", 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) wpabuf_len(respData), flags); 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (proc_version && 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt proc_version(sm, priv, flags & EAP_TLS_VERSION_MASK) < 0) 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = eap_server_tls_reassemble(data, flags, &pos, &left); 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0) { 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto done; 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (ret == 1) 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (proc_msg) 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt proc_msg(sm, priv, respData); 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_connection_get_write_alerts(sm->ssl_ctx, data->conn) > 1) { 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "SSL: Locally detected fatal error in " 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "TLS processing"); 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdone: 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_server_tls_free_in_buf(data); 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 455