18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP peer: EAP-TLS/PEAP/TTLS/FAST common functions 334af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt * Copyright (c) 2004-2013, 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#include "eap_config.h" 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidtstatic struct wpabuf * eap_tls_msg_alloc(EapType type, size_t payload_len, 2061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt u8 code, u8 identifier) 2161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt{ 2261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (type == EAP_UNAUTH_TLS_TYPE) 2361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return eap_msg_alloc(EAP_VENDOR_UNAUTH_TLS, 2461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt EAP_VENDOR_TYPE_UNAUTH_TLS, payload_len, 2561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt code, identifier); 26f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt if (type == EAP_WFA_UNAUTH_TLS_TYPE) 27f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt return eap_msg_alloc(EAP_VENDOR_WFA_NEW, 28f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt EAP_VENDOR_WFA_UNAUTH_TLS, payload_len, 29f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt code, identifier); 3061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt return eap_msg_alloc(EAP_VENDOR_IETF, type, payload_len, code, 3161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt identifier); 3261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt} 3361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 3461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_tls_check_blob(struct eap_sm *sm, const char **name, 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 **data, size_t *data_len) 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpa_config_blob *blob; 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*name == NULL || os_strncmp(*name, "blob://", 7) != 0) 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt blob = eap_get_config_blob(sm, *name + 7); 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (blob == NULL) { 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "%s: Named configuration blob '%s' not " 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "found", __func__, *name + 7); 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *name = NULL; 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *data = blob->data; 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *data_len = blob->len; 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_tls_params_flags(struct tls_connection_params *params, 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *txt) 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (txt == NULL) 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strstr(txt, "tls_allow_md5=1")) 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->flags |= TLS_CONN_ALLOW_SIGN_RSA_MD5; 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (os_strstr(txt, "tls_disable_time_checks=1")) 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->flags |= TLS_CONN_DISABLE_TIME_CHECKS; 6761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (os_strstr(txt, "tls_disable_session_ticket=1")) 6861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt params->flags |= TLS_CONN_DISABLE_SESSION_TICKET; 6961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (os_strstr(txt, "tls_disable_session_ticket=0")) 7061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt params->flags &= ~TLS_CONN_DISABLE_SESSION_TICKET; 71d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (os_strstr(txt, "tls_disable_tlsv1_0=1")) 72d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt params->flags |= TLS_CONN_DISABLE_TLSv1_0; 73d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (os_strstr(txt, "tls_disable_tlsv1_0=0")) 74d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt params->flags &= ~TLS_CONN_DISABLE_TLSv1_0; 7513ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt if (os_strstr(txt, "tls_disable_tlsv1_1=1")) 7613ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt params->flags |= TLS_CONN_DISABLE_TLSv1_1; 7713ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt if (os_strstr(txt, "tls_disable_tlsv1_1=0")) 7813ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt params->flags &= ~TLS_CONN_DISABLE_TLSv1_1; 7913ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt if (os_strstr(txt, "tls_disable_tlsv1_2=1")) 8013ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt params->flags |= TLS_CONN_DISABLE_TLSv1_2; 8113ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt if (os_strstr(txt, "tls_disable_tlsv1_2=0")) 8213ca8d8ea51a1aa5e24c6c956473a11b0c7daed4Dmitry Shmidt params->flags &= ~TLS_CONN_DISABLE_TLSv1_2; 831b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidt if (os_strstr(txt, "tls_ext_cert_check=1")) 841b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidt params->flags |= TLS_CONN_EXT_CERT_CHECK; 851b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidt if (os_strstr(txt, "tls_ext_cert_check=0")) 861b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidt params->flags &= ~TLS_CONN_EXT_CERT_CHECK; 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_tls_params_from_conf1(struct tls_connection_params *params, 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config) 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->ca_cert = (char *) config->ca_cert; 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->ca_path = (char *) config->ca_path; 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->client_cert = (char *) config->client_cert; 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->private_key = (char *) config->private_key; 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->private_key_passwd = (char *) config->private_key_passwd; 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->dh_file = (char *) config->dh_file; 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->subject_match = (char *) config->subject_match; 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->altsubject_match = (char *) config->altsubject_match; 101051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt params->suffix_match = config->domain_suffix_match; 1022f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt params->domain_match = config->domain_match; 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->engine = config->engine; 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->engine_id = config->engine_id; 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->pin = config->pin; 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->key_id = config->key_id; 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->cert_id = config->cert_id; 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->ca_cert_id = config->ca_cert_id; 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_tls_params_flags(params, config->phase1); 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_tls_params_from_conf2(struct tls_connection_params *params, 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config) 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->ca_cert = (char *) config->ca_cert2; 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->ca_path = (char *) config->ca_path2; 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->client_cert = (char *) config->client_cert2; 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->private_key = (char *) config->private_key2; 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->private_key_passwd = (char *) config->private_key2_passwd; 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->dh_file = (char *) config->dh_file2; 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->subject_match = (char *) config->subject_match2; 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->altsubject_match = (char *) config->altsubject_match2; 124051af73b8f8014eff33330aead0f36944b3403e6Dmitry Shmidt params->suffix_match = config->domain_suffix_match2; 1252f74e36e84064ffa32f82f3decf36b653c7e4fadDmitry Shmidt params->domain_match = config->domain_match2; 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->engine = config->engine2; 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->engine_id = config->engine2_id; 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->pin = config->pin2; 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->key_id = config->key2_id; 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->cert_id = config->cert2_id; 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt params->ca_cert_id = config->ca_cert2_id; 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_tls_params_flags(params, config->phase2); 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_tls_params_from_conf(struct eap_sm *sm, 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_ssl_data *data, 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection_params *params, 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config, int phase2) 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memset(params, 0, sizeof(*params)); 14261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (sm->workaround && data->eap_type != EAP_TYPE_FAST) { 14361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt /* 14461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * Some deployed authentication servers seem to be unable to 14561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * handle the TLS Session Ticket extension (they are supposed 14661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * to ignore unrecognized TLS extensions, but end up rejecting 14761d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * the ClientHello instead). As a workaround, disable use of 14861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * TLS Sesson Ticket extension for EAP-TLS, EAP-PEAP, and 14961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * EAP-TTLS (EAP-FAST uses session ticket, so any server that 15061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * supports EAP-FAST does not need this workaround). 15161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt */ 15261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt params->flags |= TLS_CONN_DISABLE_SESSION_TICKET; 15361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt } 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (phase2) { 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: using phase2 config options"); 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_tls_params_from_conf2(params, config); 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: using phase1 config options"); 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_tls_params_from_conf1(params, config); 1606c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt if (data->eap_type == EAP_TYPE_FAST) 1616c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt params->flags |= TLS_CONN_EAP_FAST; 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Use blob data, if available. Otherwise, leave reference to external 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * file as-is. 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_tls_check_blob(sm, ¶ms->ca_cert, ¶ms->ca_cert_blob, 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ¶ms->ca_cert_blob_len) || 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_tls_check_blob(sm, ¶ms->client_cert, 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ¶ms->client_cert_blob, 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ¶ms->client_cert_blob_len) || 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_tls_check_blob(sm, ¶ms->private_key, 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ¶ms->private_key_blob, 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ¶ms->private_key_blob_len) || 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_tls_check_blob(sm, ¶ms->dh_file, ¶ms->dh_blob, 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ¶ms->dh_blob_len)) { 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "SSL: Failed to get configuration blobs"); 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1826c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt params->openssl_ciphers = config->openssl_ciphers; 1836c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt 1841b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidt sm->ext_cert_check = !!(params->flags & TLS_CONN_EXT_CERT_CHECK); 1851b46775bb44f06b3cc285481ff5f7a673559ed7dDmitry Shmidt 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_tls_init_connection(struct eap_sm *sm, 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_ssl_data *data, 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config, 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection_params *params) 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 19734af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt if (config->ocsp) 19834af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt params->flags |= TLS_CONN_REQUEST_OCSP; 199d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt if (config->ocsp >= 2) 20034af306c42b7ccf956508e7cd23f0ba90606e360Dmitry Shmidt params->flags |= TLS_CONN_REQUIRE_OCSP; 201d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt if (config->ocsp == 3) 202d97138ded63ac5388da3a2b63dea563c8b44c8ecDmitry Shmidt params->flags |= TLS_CONN_REQUIRE_OCSP_ALL; 20304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt data->conn = tls_connection_init(data->ssl_ctx); 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->conn == NULL) { 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "SSL: Failed to initialize new TLS " 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "connection"); 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 21004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt res = tls_connection_set_params(data->ssl_ctx, data->conn, params); 2111d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt if (res == TLS_SET_PARAMS_ENGINE_PRV_BAD_PIN) { 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 2131d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt * At this point with the pkcs11 engine the PIN is wrong. We 2141d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt * reset the PIN in the configuration to be sure to not use it 2151d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt * again and the calling function must request a new one. 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2171d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt wpa_printf(MSG_INFO, 2181d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt "TLS: Bad PIN provided, requesting a new one"); 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(config->pin); 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config->pin = NULL; 2211d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt eap_sm_request_pin(sm); 2221d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt sm->ignore = TRUE; 2231d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt } else if (res == TLS_SET_PARAMS_ENGINE_PRV_INIT_FAILED) { 2241d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to initialize engine"); 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (res == TLS_SET_PARAMS_ENGINE_PRV_VERIFY_FAILED) { 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to load private key"); 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ignore = TRUE; 2281d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt } 2291d755d025b206e22b06aeb322e25a79f98ca7777Dmitry Shmidt if (res) { 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "TLS: Failed to set TLS connection " 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "parameters"); 23204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt tls_connection_deinit(data->ssl_ctx, data->conn); 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->conn = NULL; 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_peer_tls_ssl_init - Initialize shared TLS functionality 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: Data for TLS processing 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @config: Pointer to the network configuration 24661d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt * @eap_type: EAP method used in Phase 1 (EAP_TYPE_TLS/PEAP/TTLS/FAST) 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to initialize shared TLS functionality for EAP-TLS, 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-PEAP, EAP-TTLS, and EAP-FAST. 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_peer_tls_ssl_init(struct eap_sm *sm, struct eap_ssl_data *data, 25361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt struct eap_peer_config *config, u8 eap_type) 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct tls_connection_params params; 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config == NULL) 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->eap = sm; 26161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt data->eap_type = eap_type; 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->phase2 = sm->init_phase2; 26304949598a23f501be6eec21697465fd46a28840aDmitry Shmidt data->ssl_ctx = sm->init_phase2 && sm->ssl_ctx2 ? sm->ssl_ctx2 : 26404949598a23f501be6eec21697465fd46a28840aDmitry Shmidt sm->ssl_ctx; 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_tls_params_from_conf(sm, data, ¶ms, config, data->phase2) < 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 0) 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_tls_init_connection(sm, data, config, ¶ms) < 0) 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_out_limit = config->fragment_size; 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->phase2) { 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Limit the fragment size in the inner TLS authentication 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * since the outer authentication with EAP-PEAP does not yet 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * support fragmentation */ 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_out_limit > 100) 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_out_limit -= 100; 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config->phase1 && 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_strstr(config->phase1, "include_tls_length=1")) { 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Include TLS Message Length in " 2848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "unfragmented packets"); 2858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->include_tls_length = 1; 2868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 2898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 2938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_peer_tls_ssl_deinit - Deinitialize shared TLS functionality 2948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 2958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: Data for TLS processing 2968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 2978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function deinitializes shared TLS functionality that was initialized 2988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * with eap_peer_tls_ssl_init(). 2998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_peer_tls_ssl_deinit(struct eap_sm *sm, struct eap_ssl_data *data) 3018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 30204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt tls_connection_deinit(data->ssl_ctx, data->conn); 3038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_peer_tls_reset_input(data); 3048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_peer_tls_reset_output(data); 3058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 3098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_peer_tls_derive_key - Derive a key based on TLS session data 3108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 3118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: Data for TLS processing 3128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @label: Label string for deriving the keys, e.g., "client EAP encryption" 3138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Length of the key material to generate (usually 64 for MSK) 3148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to allocated key on success or %NULL on failure 3158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 3168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function uses TLS-PRF to generate pseudo-random data based on the TLS 3178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * session data (client/server random and master key). Each key type may use a 3188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * different label to bind the key usage into the generated material. 3198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 3208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * The caller is responsible for freeing the returned buffer. 3218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtu8 * eap_peer_tls_derive_key(struct eap_sm *sm, struct eap_ssl_data *data, 3238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *label, size_t len) 3248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 325af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt u8 *out; 3268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out = os_malloc(len); 3288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (out == NULL) 3298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 3308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 331849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt if (tls_connection_export_key(data->ssl_ctx, data->conn, label, out, 332849734c8d1847920ed7042463f7480b1e0c1dfeaDmitry Shmidt len)) { 333af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt os_free(out); 334af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt return NULL; 335af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt } 3368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return out; 3388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 3398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 342f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * eap_peer_tls_derive_session_id - Derive a Session-Id based on TLS data 343f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 344f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * @data: Data for TLS processing 345f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * @eap_type: EAP method used in Phase 1 (EAP_TYPE_TLS/PEAP/TTLS/FAST) 346f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * @len: Pointer to length of the session ID generated 347f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * Returns: Pointer to allocated Session-Id on success or %NULL on failure 348f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * 349f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * This function derive the Session-Id based on the TLS session data 350f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * (client/server random and method type). 351f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * 352f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt * The caller is responsible for freeing the returned buffer. 353f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt */ 354f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidtu8 * eap_peer_tls_derive_session_id(struct eap_sm *sm, 355f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt struct eap_ssl_data *data, u8 eap_type, 356f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt size_t *len) 357f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt{ 358d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt struct tls_random keys; 359f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt u8 *out; 360f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 3610e58d9be2680098adccaadeadf31375ca54b7256Dmitry Shmidt if (tls_connection_get_random(sm->ssl_ctx, data->conn, &keys) || 3620e58d9be2680098adccaadeadf31375ca54b7256Dmitry Shmidt keys.client_random == NULL || keys.server_random == NULL) 363f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return NULL; 364f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 365f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt *len = 1 + keys.client_random_len + keys.server_random_len; 366f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt out = os_malloc(*len); 367f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt if (out == NULL) 368f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return NULL; 369f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 370f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt /* Session-Id = EAP type || client.random || server.random */ 371f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt out[0] = eap_type; 372f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt os_memcpy(out + 1, keys.client_random, keys.client_random_len); 373f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt os_memcpy(out + 1 + keys.client_random_len, keys.server_random, 3746c0da2bb83f6915d8260912362692d1a742e057bDmitry Shmidt keys.server_random_len); 375f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 376f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt return out; 377f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt} 378f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 379f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt 380f86232838cf712377867cb42417c1613ab5dc425Dmitry Shmidt/** 3818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_peer_tls_reassemble_fragment - Reassemble a received fragment 3828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: Data for TLS processing 3838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @in_data: Next incoming TLS segment 3848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, 1 if more data is needed for the full message, or 3858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * -1 on error 3868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 3878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_peer_tls_reassemble_fragment(struct eap_ssl_data *data, 3888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *in_data) 3898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 3908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t tls_in_len, in_len; 3918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_in_len = data->tls_in ? wpabuf_len(data->tls_in) : 0; 3938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt in_len = in_data ? wpabuf_len(in_data) : 0; 3948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 3958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_in_len + in_len == 0) { 3968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* No message data received?! */ 3978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_WARNING, "SSL: Invalid reassembly state: " 3988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "tls_in_left=%lu tls_in_len=%lu in_len=%lu", 3998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) data->tls_in_left, 4008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) tls_in_len, 4018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) in_len); 4028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_peer_tls_reset_input(data); 4038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_in_len + in_len > 65536) { 4078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 4088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Limit length to avoid rogue servers from causing large 4098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * memory allocations. 4108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "SSL: Too long TLS fragment (size over " 4128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "64 kB)"); 4138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_peer_tls_reset_input(data); 4148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (in_len > data->tls_in_left) { 4188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Sender is doing something odd - reject message */ 4198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "SSL: more data than TLS message length " 4208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "indicated"); 4218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_peer_tls_reset_input(data); 4228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (wpabuf_resize(&data->tls_in, in_len) < 0) { 4268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "SSL: Could not allocate memory for TLS " 4278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "data"); 4288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_peer_tls_reset_input(data); 4298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 4308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (in_data) 4328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_buf(data->tls_in, in_data); 4338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_in_left -= in_len; 4348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_in_left > 0) { 4368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Need %lu bytes more input " 4378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "data", (unsigned long) data->tls_in_left); 4388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 4398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 4428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 4468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_peer_tls_data_reassemble - Reassemble TLS data 4478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: Data for TLS processing 4488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @in_data: Next incoming TLS segment 4498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @need_more_input: Variable for returning whether more input data is needed 4508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to reassemble this TLS packet 4518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to output data, %NULL on error or when more data is needed 4528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * for the full message (in which case, *need_more_input is also set to 1). 4538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 4548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function reassembles TLS fragments. Caller must not free the returned 4558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * data buffer since an internal pointer to it is maintained. 4568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic const struct wpabuf * eap_peer_tls_data_reassemble( 4588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_ssl_data *data, const struct wpabuf *in_data, 4598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int *need_more_input) 4608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *need_more_input = 0; 4628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_in_left > wpabuf_len(in_data) || data->tls_in) { 4648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Message has fragments */ 4658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res = eap_peer_tls_reassemble_fragment(data, in_data); 4668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res) { 4678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == 1) 4688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *need_more_input = 1; 4698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Message is now fully reassembled. */ 4738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 4748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* No fragments in this message, so just make a copy of it. */ 4758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_in_left = 0; 4768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_in = wpabuf_dup(in_data); 4778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_in == NULL) 4788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 4798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 4808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return data->tls_in; 4828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 4838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 4858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 4868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_tls_process_input - Process incoming TLS message 4878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 4888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: Data for TLS processing 4898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @in_data: Message received from the server 4908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @out_data: Buffer for returning a pointer to application data (if available) 4918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, 1 if more input data is needed, 2 if application data 4928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * is available, -1 on failure 4938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 4948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_tls_process_input(struct eap_sm *sm, struct eap_ssl_data *data, 495cc00d5dc8483e32158b2ba61ea44b0c38d790ed7Dmitry Shmidt const struct wpabuf *in_data, 4968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf **out_data) 4978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 4988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *msg; 4998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int need_more_input; 5008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *appl_data; 5018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 502cc00d5dc8483e32158b2ba61ea44b0c38d790ed7Dmitry Shmidt msg = eap_peer_tls_data_reassemble(data, in_data, &need_more_input); 5038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg == NULL) 5048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return need_more_input ? 1 : -1; 5058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Full TLS message reassembled - continue handshake processing */ 5078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_out) { 5088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* This should not happen.. */ 5098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "SSL: eap_tls_process_input - pending " 5108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "tls_out data even though tls_out_len = 0"); 5118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(data->tls_out); 5128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt WPA_ASSERT(data->tls_out == NULL); 5138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt appl_data = NULL; 51504949598a23f501be6eec21697465fd46a28840aDmitry Shmidt data->tls_out = tls_connection_handshake(data->ssl_ctx, data->conn, 5168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg, &appl_data); 5178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_peer_tls_reset_input(data); 5198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (appl_data && 52104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt tls_connection_established(data->ssl_ctx, data->conn) && 52204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt !tls_connection_get_failed(data->ssl_ctx, data->conn)) { 5238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_buf_key(MSG_MSGDUMP, "SSL: Application data", 5248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt appl_data); 5258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *out_data = appl_data; 5268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 2; 5278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(appl_data); 5308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 5328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 5338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 5368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_tls_process_output - Process outgoing TLS message 5378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: Data for TLS processing 5388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @eap_type: EAP type (EAP_TYPE_TLS, EAP_TYPE_PEAP, ...) 5398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @peap_version: Version number for EAP-PEAP/TTLS 5408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @id: EAP identifier for the response 5418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ret: Return value to use on success 5428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @out_data: Buffer for returning the allocated output buffer 5438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: ret (0 or 1) on success, -1 on failure 5448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_tls_process_output(struct eap_ssl_data *data, EapType eap_type, 5468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int peap_version, u8 id, int ret, 5478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf **out_data) 5488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 5498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t len; 5508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *flags; 5518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int more_fragments, length_included; 5528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_out == NULL) 5548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = wpabuf_len(data->tls_out) - data->tls_out_pos; 5568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: %lu bytes left to be sent out (of total " 5578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "%lu bytes)", 5588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) len, 5598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) wpabuf_len(data->tls_out)); 5608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 5628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Limit outgoing message to the configured maximum size. Fragment 5638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * message if needed. 5648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (len > data->tls_out_limit) { 5668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt more_fragments = 1; 5678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len = data->tls_out_limit; 5688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: sending %lu bytes, more fragments " 5698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "will follow", (unsigned long) len); 5708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else 5718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt more_fragments = 0; 5728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt length_included = data->tls_out_pos == 0 && 5748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (wpabuf_len(data->tls_out) > data->tls_out_limit || 5758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->include_tls_length); 5768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!length_included && 5778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_type == EAP_TYPE_PEAP && peap_version == 0 && 5788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt !tls_connection_established(data->eap->ssl_ctx, data->conn)) { 5798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 5808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Windows Server 2008 NPS really wants to have the TLS Message 5818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * length included in phase 0 even for unfragmented frames or 5828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * it will get very confused with Compound MAC calculation and 5838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Outer TLVs. 5848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 5858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt length_included = 1; 5868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 5878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 58861d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt *out_data = eap_tls_msg_alloc(eap_type, 1 + length_included * 4 + len, 58961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt EAP_CODE_RESPONSE, id); 5908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*out_data == NULL) 5918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 5928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 5938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt flags = wpabuf_put(*out_data, 1); 5948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *flags = peap_version; 5958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (more_fragments) 5968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *flags |= EAP_TLS_FLAGS_MORE_FRAGMENTS; 5978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (length_included) { 5988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *flags |= EAP_TLS_FLAGS_LENGTH_INCLUDED; 5998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_be32(*out_data, wpabuf_len(data->tls_out)); 6008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_data(*out_data, 6038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_head_u8(data->tls_out) + data->tls_out_pos, 6048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt len); 6058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_out_pos += len; 6068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!more_fragments) 6088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_peer_tls_reset_output(data); 6098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 6118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 6128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 6158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_peer_tls_process_helper - Process TLS handshake message 6168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 6178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: Data for TLS processing 6188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @eap_type: EAP type (EAP_TYPE_TLS, EAP_TYPE_PEAP, ...) 6198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @peap_version: Version number for EAP-PEAP/TTLS 6208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @id: EAP identifier for the response 6218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @in_data: Message received from the server 6228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @out_data: Buffer for returning a pointer to the response message 6238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, 1 if more input data is needed, 2 if application data 6248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * is available, or -1 on failure 6258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 6268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function can be used to process TLS handshake messages. It reassembles 6278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the received fragments and uses a TLS library to process the messages. The 6288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * response data from the TLS library is fragmented to suitable output messages 6298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * that the caller can send out. 6308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 6318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * out_data is used to return the response message if the return value of this 6328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * function is 0, 2, or -1. In case of failure, the message is likely a TLS 6338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * alarm message. The caller is responsible for freeing the allocated buffer if 6348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * *out_data is not %NULL. 6358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 6368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is called for each received TLS message during the TLS 6378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * handshake after eap_peer_tls_process_init() call and possible processing of 6388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * TLS Flags field. Once the handshake has been completed, i.e., when 6398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * tls_connection_established() returns 1, EAP method specific decrypting of 6408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the tunneled data is used. 6418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_peer_tls_process_helper(struct eap_sm *sm, struct eap_ssl_data *data, 6438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EapType eap_type, int peap_version, 644cc00d5dc8483e32158b2ba61ea44b0c38d790ed7Dmitry Shmidt u8 id, const struct wpabuf *in_data, 6458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf **out_data) 6468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 6478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret = 0; 6488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *out_data = NULL; 6508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 651cc00d5dc8483e32158b2ba61ea44b0c38d790ed7Dmitry Shmidt if (data->tls_out && wpabuf_len(data->tls_out) > 0 && 652cc00d5dc8483e32158b2ba61ea44b0c38d790ed7Dmitry Shmidt wpabuf_len(in_data) > 0) { 6538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Received non-ACK when output " 6548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "fragments are waiting to be sent out"); 6558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_out == NULL || wpabuf_len(data->tls_out) == 0) { 6598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 6608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * No more data to send out - expect to receive more data from 6618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the AS. 6628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 663cc00d5dc8483e32158b2ba61ea44b0c38d790ed7Dmitry Shmidt int res = eap_tls_process_input(sm, data, in_data, out_data); 6648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res) { 6658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 6668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Input processing failed (res = -1) or more data is 6678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * needed (res = 1). 6688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return res; 6708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 6738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * The incoming message has been reassembled and processed. The 6748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * response was allocated into data->tls_out buffer. 6758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 6788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_out == NULL) { 6798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 6808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * No outgoing fragments remaining from the previous message 6818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * and no new message generated. This indicates an error in TLS 6828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * processing. 6838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 6848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_peer_tls_reset_output(data); 6858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 6868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 6878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 68804949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (tls_connection_get_failed(data->ssl_ctx, data->conn)) { 6898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TLS processing has failed - return error */ 6908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Failed - tls_out available to " 691d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "report error (len=%u)", 692d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt (unsigned int) wpabuf_len(data->tls_out)); 6938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = -1; 6948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: clean pin if engine used? */ 695d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (wpabuf_len(data->tls_out) == 0) { 696d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt wpabuf_free(data->tls_out); 697d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt data->tls_out = NULL; 698d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return -1; 699d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt } 7008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 702d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (wpabuf_len(data->tls_out) == 0) { 7038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 7048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * TLS negotiation should now be complete since all other cases 7058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * needing more data should have been caught above based on 7068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the TLS Message Length field. 7078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: No data to be sent out"); 7098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(data->tls_out); 7108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_out = NULL; 7118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 1; 7128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 7138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* Send the pending message (in fragments, if needed). */ 7158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eap_tls_process_output(data, eap_type, peap_version, id, ret, 7168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out_data); 7178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 7218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_peer_tls_build_ack - Build a TLS ACK frame 7228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @id: EAP identifier for the response 7238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @eap_type: EAP type (EAP_TYPE_TLS, EAP_TYPE_PEAP, ...) 7248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @peap_version: Version number for EAP-PEAP/TTLS 7258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to the allocated ACK frame or %NULL on failure 7268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct wpabuf * eap_peer_tls_build_ack(u8 id, EapType eap_type, 7288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int peap_version) 7298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 7318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 73261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt resp = eap_tls_msg_alloc(eap_type, 1, EAP_CODE_RESPONSE, id); 7338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp == NULL) 7348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 7358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Building ACK (type=%d id=%d ver=%d)", 7368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (int) eap_type, id, peap_version); 7378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(resp, peap_version); /* Flags */ 7388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 7398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 7438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_peer_tls_reauth_init - Re-initialize shared TLS for session resumption 7448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 7458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: Data for TLS processing 7468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 7478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_peer_tls_reauth_init(struct eap_sm *sm, struct eap_ssl_data *data) 7498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 7508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_peer_tls_reset_input(data); 7518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_peer_tls_reset_output(data); 75204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt return tls_connection_shutdown(data->ssl_ctx, data->conn); 7538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 7578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_peer_tls_status - Get TLS status 7588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 7598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: Data for TLS processing 7608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buf: Buffer for status information 7618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @buflen: Maximum buffer length 7628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @verbose: Whether to include verbose status information 7638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Number of bytes written to buf. 7648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 7658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_peer_tls_status(struct eap_sm *sm, struct eap_ssl_data *data, 7668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *buf, size_t buflen, int verbose) 7678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 768d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt char version[20], name[128]; 7698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int len = 0, ret; 7708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 771d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (tls_get_version(data->ssl_ctx, data->conn, version, 772d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt sizeof(version)) < 0) 773d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt version[0] = '\0'; 774d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (tls_get_cipher(data->ssl_ctx, data->conn, name, sizeof(name)) < 0) 775d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt name[0] = '\0'; 776d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt 777d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt ret = os_snprintf(buf + len, buflen - len, 778d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "eap_tls_version=%s\n" 779d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "EAP TLS cipher=%s\n" 780d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt "tls_session_reused=%d\n", 781d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt version, name, 782d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt tls_connection_resumed(data->ssl_ctx, data->conn)); 783d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt if (os_snprintf_error(buflen - len, ret)) 784d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt return len; 785d80a401aed31d06f261efd19223cf55d1a2a8228Dmitry Shmidt len += ret; 7868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return len; 7888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 7898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 7918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 7928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_peer_tls_process_init - Initial validation/processing of EAP requests 7938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 7948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: Data for TLS processing 7958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @eap_type: EAP type (EAP_TYPE_TLS, EAP_TYPE_PEAP, ...) 7968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @ret: Return values from EAP request validation and processing 7978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @reqData: EAP request to be processed (eapReqData) 7988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @len: Buffer for returning length of the remaining payload 7998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @flags: Buffer for returning TLS flags 8008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: Pointer to payload after TLS flags and length or %NULL on failure 8018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 8028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function validates the EAP header and processes the optional TLS 8038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Message Length field. If this is the first fragment of a TLS message, the 8048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * TLS reassembly code is initialized to receive the indicated number of bytes. 8058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 8068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP-TLS, EAP-PEAP, EAP-TTLS, and EAP-FAST methods are expected to use this 8078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * function as the first step in processing received messages. They will need 8088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * to process the flags (apart from Message Length Included) that are returned 8098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * through the flags pointer and the message payload that will be returned (and 8108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the length is returned through the len pointer). Return values (ret) are set 8118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * for continuation of EAP method processing. The caller is responsible for 8128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * setting these to indicate completion (either success or failure) based on 8138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the authentication result. 8148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 8158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtconst u8 * eap_peer_tls_process_init(struct eap_sm *sm, 8168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_ssl_data *data, 8178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EapType eap_type, 8188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method_ret *ret, 8198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *reqData, 8208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t *len, u8 *flags) 8218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 8228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos; 8238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left; 8248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt unsigned int tls_msg_len; 8258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 82604949598a23f501be6eec21697465fd46a28840aDmitry Shmidt if (tls_get_errors(data->ssl_ctx)) { 8278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "SSL: TLS errors detected"); 8288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->ignore = TRUE; 8298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 8308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 83261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt if (eap_type == EAP_UNAUTH_TLS_TYPE) 83361d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos = eap_hdr_validate(EAP_VENDOR_UNAUTH_TLS, 83461d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt EAP_VENDOR_TYPE_UNAUTH_TLS, reqData, 83561d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt &left); 836f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt else if (eap_type == EAP_WFA_UNAUTH_TLS_TYPE) 837f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt pos = eap_hdr_validate(EAP_VENDOR_WFA_NEW, 838f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt EAP_VENDOR_WFA_UNAUTH_TLS, reqData, 839f21452aea786ac056eb01f1cbba4f553bd502747Dmitry Shmidt &left); 84061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt else 84161d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt pos = eap_hdr_validate(EAP_VENDOR_IETF, eap_type, reqData, 84261d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt &left); 8438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL) { 8448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->ignore = TRUE; 8458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 8468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left == 0) { 8488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Invalid TLS message: no Flags " 8498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "octet included"); 8508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (!sm->workaround) { 8518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->ignore = TRUE; 8528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 8538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Workaround - assume no Flags " 8568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "indicates ACK frame"); 8578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *flags = 0; 8588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 8598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *flags = *pos++; 8608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left--; 8618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: Received packet(len=%lu) - " 8638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "Flags 0x%02x", (unsigned long) wpabuf_len(reqData), 8648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *flags); 8658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*flags & EAP_TLS_FLAGS_LENGTH_INCLUDED) { 8668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (left < 4) { 8678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "SSL: Short frame with TLS " 8688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "length"); 8698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->ignore = TRUE; 8708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 8718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_msg_len = WPA_GET_BE32(pos); 8738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "SSL: TLS Message Length: %d", 8748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt tls_msg_len); 8758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_in_left == 0) { 8768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_in_total = tls_msg_len; 8778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_in_left = tls_msg_len; 8788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(data->tls_in); 8798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_in = NULL; 8808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos += 4; 8828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left -= 4; 883d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt 884d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt if (left > tls_msg_len) { 885d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt wpa_printf(MSG_INFO, "SSL: TLS Message Length (%d " 886d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "bytes) smaller than this fragment (%d " 887d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt "bytes)", (int) tls_msg_len, (int) left); 888d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt ret->ignore = TRUE; 889d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt return NULL; 890d5e4923d04122f81300fa68fb07d64ede28fd44dDmitry Shmidt } 8918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 8928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->ignore = FALSE; 8948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->methodState = METHOD_MAY_CONT; 8958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->decision = DECISION_FAIL; 8968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->allowNotifications = TRUE; 8978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 8988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = left; 8998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return pos; 9008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 9048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_peer_tls_reset_input - Reset input buffers 9058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: Data for TLS processing 9068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 9078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function frees any allocated memory for input buffers and resets input 9088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * state. 9098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 9108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_peer_tls_reset_input(struct eap_ssl_data *data) 9118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_in_left = data->tls_in_total = 0; 9138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(data->tls_in); 9148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_in = NULL; 9158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 9198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_peer_tls_reset_output - Reset output buffers 9208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: Data for TLS processing 9218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 9228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function frees any allocated memory for output buffers and resets 9238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * output state. 9248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 9258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtvoid eap_peer_tls_reset_output(struct eap_ssl_data *data) 9268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_out_pos = 0; 9288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(data->tls_out); 9298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->tls_out = NULL; 9308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 9348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_peer_tls_decrypt - Decrypt received phase 2 TLS message 9358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 9368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: Data for TLS processing 9378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @in_data: Message received from the server 9388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @in_decrypted: Buffer for returning a pointer to the decrypted message 9398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, 1 if more input data is needed, or -1 on failure 9408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 9418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_peer_tls_decrypt(struct eap_sm *sm, struct eap_ssl_data *data, 9428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *in_data, 9438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf **in_decrypted) 9448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *msg; 9468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int need_more_input; 9478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt msg = eap_peer_tls_data_reassemble(data, in_data, &need_more_input); 9498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (msg == NULL) 9508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return need_more_input ? 1 : -1; 9518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 95204949598a23f501be6eec21697465fd46a28840aDmitry Shmidt *in_decrypted = tls_connection_decrypt(data->ssl_ctx, data->conn, msg); 9538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_peer_tls_reset_input(data); 9548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*in_decrypted == NULL) { 9558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "SSL: Failed to decrypt Phase 2 data"); 9568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 9598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 9638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_peer_tls_encrypt - Encrypt phase 2 TLS message 9648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @sm: Pointer to EAP state machine allocated with eap_peer_sm_init() 9658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @data: Data for TLS processing 9668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @eap_type: EAP type (EAP_TYPE_TLS, EAP_TYPE_PEAP, ...) 9678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @peap_version: Version number for EAP-PEAP/TTLS 9688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @id: EAP identifier for the response 9698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @in_data: Plaintext phase 2 data to encrypt or %NULL to continue fragments 9708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @out_data: Buffer for returning a pointer to the encrypted response message 9718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 9728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 9738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_peer_tls_encrypt(struct eap_sm *sm, struct eap_ssl_data *data, 9748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EapType eap_type, int peap_version, u8 id, 9758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *in_data, 9768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf **out_data) 9778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 9788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (in_data) { 9798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_peer_tls_reset_output(data); 98004949598a23f501be6eec21697465fd46a28840aDmitry Shmidt data->tls_out = tls_connection_encrypt(data->ssl_ctx, 98104949598a23f501be6eec21697465fd46a28840aDmitry Shmidt data->conn, in_data); 9828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->tls_out == NULL) { 9838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "SSL: Failed to encrypt Phase 2 " 9848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "data (in_len=%lu)", 9858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (unsigned long) wpabuf_len(in_data)); 9868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_peer_tls_reset_output(data); 9878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 9888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 9908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eap_tls_process_output(data, eap_type, peap_version, id, 0, 9928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt out_data); 9938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 9948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 9968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 9978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_peer_select_phase2_methods - Select phase 2 EAP method 9988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @config: Pointer to the network configuration 9998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @prefix: 'phase2' configuration prefix, e.g., "auth=" 10008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @types: Buffer for returning allocated list of allowed EAP methods 10018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @num_types: Buffer for returning number of allocated EAP methods 10028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 10038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * 10048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This function is used to parse EAP method list and select allowed methods 10058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * for Phase2 authentication. 10068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 10078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_peer_select_phase2_methods(struct eap_peer_config *config, 10088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const char *prefix, 10098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method_type **types, 10108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t *num_types) 10118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt char *start, *pos, *buf; 10138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method_type *methods = NULL, *_methods; 1014af9da3180dc20f57df1fc1e1811f3df9fa9e6ab5Dmitry Shmidt u32 method; 10158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t num_methods = 0, prefix_len; 10168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config == NULL || config->phase2 == NULL) 10188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt goto get_defaults; 10198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = buf = os_strdup(config->phase2); 10218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (buf == NULL) 10228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt prefix_len = os_strlen(prefix); 10258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt while (start && *start != '\0') { 10278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int vendor; 10288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strstr(start, prefix); 10298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL) 10308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt break; 10318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (start != pos && *(pos - 1) != ' ') { 10328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = pos + prefix_len; 10338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt continue; 10348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = pos + prefix_len; 10378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = os_strchr(start, ' '); 10388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos) 10398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *pos++ = '\0'; 10408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt method = eap_get_phase2_type(start, &vendor); 10418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (vendor == EAP_VENDOR_IETF && method == EAP_TYPE_NONE) { 10428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "TLS: Unsupported Phase2 EAP " 10438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "method '%s'", start); 10440e58d9be2680098adccaadeadf31375ca54b7256Dmitry Shmidt os_free(methods); 10450e58d9be2680098adccaadeadf31375ca54b7256Dmitry Shmidt os_free(buf); 10460e58d9be2680098adccaadeadf31375ca54b7256Dmitry Shmidt return -1; 10478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 10488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_methods++; 104961d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt _methods = os_realloc_array(methods, num_methods, 105061d9df3e62aaa0e87ad05452fcb95142159a17b6Dmitry Shmidt sizeof(*methods)); 10518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (_methods == NULL) { 10528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(methods); 10538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 10548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt methods = _methods; 10578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt methods[num_methods - 1].vendor = vendor; 10588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt methods[num_methods - 1].method = method; 10598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt start = pos; 10628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(buf); 10658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtget_defaults: 10678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (methods == NULL) 10688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt methods = eap_get_phase2_types(config, &num_methods); 10698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (methods == NULL) { 10718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_ERROR, "TLS: No Phase2 EAP methods available"); 10728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 10738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 10748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "TLS: Phase2 EAP types", 10758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) methods, 10768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt num_methods * sizeof(struct eap_method_type)); 10778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *types = methods; 10798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *num_types = num_methods; 10808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 10828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 10838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/** 10868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * eap_peer_tls_phase2_nak - Generate EAP-Nak for Phase 2 10878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @types: Buffer for returning allocated list of allowed EAP methods 10888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @num_types: Buffer for returning number of allocated EAP methods 10898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @hdr: EAP-Request header (and the following EAP type octet) 10908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * @resp: Buffer for returning the EAP-Nak message 10918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Returns: 0 on success, -1 on failure 10928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 10938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_peer_tls_phase2_nak(struct eap_method_type *types, size_t num_types, 10948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_hdr *hdr, struct wpabuf **resp) 10958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 10968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *pos = (u8 *) (hdr + 1); 10978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t i; 10988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 10998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* TODO: add support for expanded Nak */ 11008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "TLS: Phase 2 Request: Nak type=%d", *pos); 11018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump(MSG_DEBUG, "TLS: Allowed Phase2 EAP types", 11028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (u8 *) types, num_types * sizeof(struct eap_method_type)); 11038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *resp = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_NAK, num_types, 11048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_CODE_RESPONSE, hdr->identifier); 11058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (*resp == NULL) 11068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 11078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt for (i = 0; i < num_types; i++) { 11098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (types[i].vendor == EAP_VENDOR_IETF && 11108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt types[i].method < 256) 11118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_put_u8(*resp, types[i].method); 11128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 11138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_update_len(*resp); 11158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 11168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return 0; 11178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1118