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, 47d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt int verify_peer, int eap_type) 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 49d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt u8 session_ctx[8]; 50d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt unsigned int flags = 0; 51d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 5201904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt if (sm->ssl_ctx == NULL) { 5301904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt wpa_printf(MSG_ERROR, "TLS context not initialized - cannot use TLS-based EAP method"); 5401904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt return -1; 5501904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt } 5601904cfafd75a70b9f29c0220b90bdef45595491Dmitry Shmidt 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->eap = sm; 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->phase2 = sm->init_phase2; 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->conn = tls_connection_init(sm->ssl_ctx); 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->conn == NULL) { 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "SSL: Failed to initialize new TLS " 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "connection"); 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 67818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_TLS_INTERNAL 68818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tls_connection_set_log_cb(data->conn, eap_server_tls_log_cb, sm); 69818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#ifdef CONFIG_TESTING_OPTIONS 70818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt tls_connection_set_test_flags(data->conn, sm->tls_test_flags); 71818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_TESTING_OPTIONS */ 72818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt#endif /* CONFIG_TLS_INTERNAL */ 73818ea489ef32dcdc7c098d8a336d6e1dd8996112Dmitry Shmidt 74d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (eap_type != EAP_TYPE_FAST) 75d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt flags |= TLS_CONN_DISABLE_SESSION_TICKET; 76d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt os_memcpy(session_ctx, "hostapd", 7); 77d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt session_ctx[7] = (u8) eap_type; 78d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (tls_connection_set_verify(sm->ssl_ctx, data->conn, verify_peer, 79d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt flags, session_ctx, 80d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt sizeof(session_ctx))) { 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "SSL: Failed to configure verification " 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "of TLS peer certificate"); 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_connection_deinit(sm->ssl_ctx, data->conn); 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->conn = NULL; 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_out_limit = sm->fragment_size > 0 ? sm->fragment_size : 1398; 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->phase2) { 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Limit the fragment size in the inner TLS authentication 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * since the outer authentication with EAP-PEAP does not yet 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * support fragmentation */ 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_out_limit > 100) 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_out_limit -= 100; 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_server_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data) 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_connection_deinit(sm->ssl_ctx, data->conn); 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_server_tls_free_in_buf(data); 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(data->tls_out); 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_out = NULL; 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtu8 * eap_server_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data, 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *label, size_t len) 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 112af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt u8 *out; 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out = os_malloc(len); 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (out == NULL) 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 118af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt if (tls_connection_prf(sm->ssl_ctx, data->conn, label, 0, 0, 119af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt out, len)) { 120af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt os_free(out); 121af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt return NULL; 122af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt } 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return out; 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1286c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt/** 1296c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * eap_server_tls_derive_session_id - Derive a Session-Id based on TLS data 1306c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 1316c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * @data: Data for TLS processing 1326c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * @eap_type: EAP method used in Phase 1 (EAP_TYPE_TLS/PEAP/TTLS/FAST) 1336c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * @len: Pointer to length of the session ID generated 1346c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * Returns: Pointer to allocated Session-Id on success or %NULL on failure 1356c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * 1366c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * This function derive the Session-Id based on the TLS session data 1376c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * (client/server random and method type). 1386c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * 1396c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt * The caller is responsible for freeing the returned buffer. 1406c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt */ 1416c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidtu8 * eap_server_tls_derive_session_id(struct eap_sm *sm, 1426c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt struct eap_ssl_data *data, u8 eap_type, 1436c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt size_t *len) 1446c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt{ 145d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct tls_random keys; 1466c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt u8 *out; 1476c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 148d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (tls_connection_get_random(sm->ssl_ctx, data->conn, &keys)) 1496c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return NULL; 1506c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1516c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (keys.client_random == NULL || keys.server_random == NULL) 1526c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return NULL; 1536c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1546c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt *len = 1 + keys.client_random_len + keys.server_random_len; 1556c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt out = os_malloc(*len); 1566c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (out == NULL) 1576c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return NULL; 1586c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1596c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt /* Session-Id = EAP type || client.random || server.random */ 1606c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt out[0] = eap_type; 1616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_memcpy(out + 1, keys.client_random, keys.client_random_len); 1626c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt os_memcpy(out + 1 + keys.client_random_len, keys.server_random, 1636c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt keys.server_random_len); 1646c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1656c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt return out; 1666c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt} 1676c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1686c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * eap_server_tls_build_msg(struct eap_ssl_data *data, 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int eap_type, int version, u8 id) 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *req; 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 flags; 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t send_len, plen; 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Generating Request"); 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_out == NULL) { 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "SSL: tls_out NULL in %s", __func__); 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt flags = version; 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt send_len = wpabuf_len(data->tls_out) - data->tls_out_pos; 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (1 + send_len > data->tls_out_limit) { 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt send_len = data->tls_out_limit - 1; 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt flags |= EAP_TLS_FLAGS_MORE_FRAGMENTS; 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_out_pos == 0) { 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt flags |= EAP_TLS_FLAGS_LENGTH_INCLUDED; 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt send_len -= 4; 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt plen = 1 + send_len; 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt plen += 4; 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt req = eap_tls_msg_alloc(eap_type, plen, EAP_CODE_REQUEST, id); 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req == NULL) 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(req, flags); /* Flags */ 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_be32(req, wpabuf_len(data->tls_out)); 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(req, wpabuf_head_u8(data->tls_out) + data->tls_out_pos, 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt send_len); 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_out_pos += send_len; 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_out_pos == wpabuf_len(data->tls_out)) { 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Sending out %lu bytes " 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(message sent completely)", 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) send_len); 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(data->tls_out); 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_out = NULL; 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_out_pos = 0; 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->state = MSG; 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Sending out %lu bytes " 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "(%lu more to send)", (unsigned long) send_len, 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) wpabuf_len(data->tls_out) - 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_out_pos); 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->state = WAIT_FRAG_ACK; 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return req; 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * eap_server_tls_build_ack(u8 id, int eap_type, int version) 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *req; 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 23361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt req = eap_tls_msg_alloc(eap_type, 1, EAP_CODE_REQUEST, id); 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (req == NULL) 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Building ACK"); 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(req, version); /* Flags */ 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return req; 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_server_tls_process_cont(struct eap_ssl_data *data, 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *buf, size_t len) 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Process continuation of a pending message */ 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > wpabuf_tailroom(data->tls_in)) { 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Fragment overflow"); 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(data->tls_in, buf, len); 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Received %lu bytes, waiting for %lu " 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "bytes more", (unsigned long) len, 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) wpabuf_tailroom(data->tls_in)); 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_server_tls_process_fragment(struct eap_ssl_data *data, 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 flags, u32 message_length, 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *buf, size_t len) 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Process a fragment that is not the last one of the message */ 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_in == NULL && !(flags & EAP_TLS_FLAGS_LENGTH_INCLUDED)) { 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: No Message Length field in a " 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "fragmented packet"); 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_in == NULL) { 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* First fragment of the message */ 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Limit length to avoid rogue peers from causing large 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * memory allocations. */ 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (message_length > 65536) { 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "SSL: Too long TLS fragment (size" 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt " over 64 kB)"); 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 282d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (len > message_length) { 283d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_printf(MSG_INFO, "SSL: Too much data (%d bytes) in " 284d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "first fragment of frame (TLS Message " 285d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "Length %d bytes)", 286d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt (int) len, (int) message_length); 287d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 288d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 289d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_in = wpabuf_alloc(message_length); 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_in == NULL) { 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: No memory for message"); 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(data->tls_in, buf, len); 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Received %lu bytes in first " 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "fragment, waiting for %lu bytes more", 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) wpabuf_tailroom(data->tls_in)); 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_server_tls_phase1(struct eap_sm *sm, struct eap_ssl_data *data) 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_out) { 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* This should not happen.. */ 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "SSL: pending tls_out data when " 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "processing new message"); 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(data->tls_out); 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_ASSERT(data->tls_out == NULL); 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_out = tls_connection_server_handshake(sm->ssl_ctx, 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->conn, 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_in, NULL); 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_out == NULL) { 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "SSL: TLS processing failed"); 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_connection_get_failed(sm->ssl_ctx, data->conn)) { 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TLS processing has failed - return error */ 3258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Failed - tls_out available to " 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "report error"); 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_server_tls_reassemble(struct eap_ssl_data *data, u8 flags, 3358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 **pos, size_t *left) 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int tls_msg_len = 0; 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *end = *pos + *left; 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) { 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*left < 4) { 3428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "SSL: Short frame with TLS " 3438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length"); 3448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_msg_len = WPA_GET_BE32(*pos); 3478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: TLS Message Length: %d", 3488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_msg_len); 3498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos += 4; 3508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *left -= 4; 351d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 352d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (*left > tls_msg_len) { 353d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_printf(MSG_INFO, "SSL: TLS Message Length (%d " 354d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "bytes) smaller than this fragment (%d " 355d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "bytes)", (int) tls_msg_len, (int) *left); 356d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return -1; 357d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 3588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Received packet: Flags 0x%x " 3618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Message Length %u", flags, tls_msg_len); 3628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->state == WAIT_FRAG_ACK) { 3648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*left != 0) { 3658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Unexpected payload in " 3668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "WAIT_FRAG_ACK state"); 3678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Fragment acknowledged"); 3708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 3718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_in && 3748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_server_tls_process_cont(data, *pos, end - *pos) < 0) 3758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (flags & EAP_TLS_FLAGS_MORE_FRAGMENTS) { 3788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_server_tls_process_fragment(data, flags, tls_msg_len, 3798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos, end - *pos) < 0) 3808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->state = FRAG_ACK; 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->state == FRAG_ACK) { 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: All fragments received"); 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->state = MSG; 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_in == NULL) { 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Wrap unfragmented messages as wpabuf without extra copy */ 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_set(&data->tmpbuf, *pos, end - *pos); 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_in = &data->tmpbuf; 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_server_tls_free_in_buf(struct eap_ssl_data *data) 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_in != &data->tmpbuf) 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(data->tls_in); 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_in = NULL; 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * eap_server_tls_encrypt(struct eap_sm *sm, 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_ssl_data *data, 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *plain) 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *buf; 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt buf = tls_connection_encrypt(sm->ssl_ctx, data->conn, 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt plain); 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) { 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "SSL: Failed to encrypt Phase 2 data"); 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return buf; 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_server_tls_process(struct eap_sm *sm, struct eap_ssl_data *data, 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *respData, void *priv, int eap_type, 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int (*proc_version)(struct eap_sm *sm, void *priv, 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int peer_version), 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt void (*proc_msg)(struct eap_sm *sm, void *priv, 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *respData)) 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos; 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 flags; 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left; 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret, res = 0; 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 43861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (eap_type == EAP_UNAUTH_TLS_TYPE) 43961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos = eap_hdr_validate(EAP_VENDOR_UNAUTH_TLS, 44061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt EAP_VENDOR_TYPE_UNAUTH_TLS, respData, 44161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt &left); 442f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt else if (eap_type == EAP_WFA_UNAUTH_TLS_TYPE) 443f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt pos = eap_hdr_validate(EAP_VENDOR_WFA_NEW, 444f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt EAP_VENDOR_WFA_UNAUTH_TLS, respData, 445f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt &left); 44661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt else 44761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos = eap_hdr_validate(EAP_VENDOR_IETF, eap_type, respData, 44861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt &left); 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL || left < 1) 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; /* Should not happen - frame already validated */ 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt flags = *pos++; 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left--; 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Received packet(len=%lu) - Flags 0x%02x", 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) wpabuf_len(respData), flags); 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (proc_version && 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt proc_version(sm, priv, flags & EAP_TLS_VERSION_MASK) < 0) 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = eap_server_tls_reassemble(data, flags, &pos, &left); 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret < 0) { 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto done; 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (ret == 1) 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (proc_msg) 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt proc_msg(sm, priv, respData); 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_connection_get_write_alerts(sm->ssl_ctx, data->conn) > 1) { 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "SSL: Locally detected fatal error in " 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "TLS processing"); 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = -1; 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtdone: 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_server_tls_free_in_buf(data); 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 481