139beb93cSSam Leffler /* 2*a90b9d01SCy Schubert * EAP peer method: EAP-TLS (RFC 5216, RFC 9190) 3c1d255d3SCy Schubert * Copyright (c) 2004-2008, 2012-2019, Jouni Malinen <j@w1.fi> 439beb93cSSam Leffler * 5f05cddf9SRui Paulo * This software may be distributed under the terms of the BSD license. 6f05cddf9SRui Paulo * See README for more details. 739beb93cSSam Leffler */ 839beb93cSSam Leffler 939beb93cSSam Leffler #include "includes.h" 1039beb93cSSam Leffler 1139beb93cSSam Leffler #include "common.h" 12e28a4053SRui Paulo #include "crypto/tls.h" 1339beb93cSSam Leffler #include "eap_i.h" 1439beb93cSSam Leffler #include "eap_tls_common.h" 1539beb93cSSam Leffler #include "eap_config.h" 1639beb93cSSam Leffler 1739beb93cSSam Leffler 1839beb93cSSam Leffler static void eap_tls_deinit(struct eap_sm *sm, void *priv); 1939beb93cSSam Leffler 2039beb93cSSam Leffler 2139beb93cSSam Leffler struct eap_tls_data { 2239beb93cSSam Leffler struct eap_ssl_data ssl; 2339beb93cSSam Leffler u8 *key_data; 245b9c547cSRui Paulo u8 *session_id; 255b9c547cSRui Paulo size_t id_len; 26f05cddf9SRui Paulo void *ssl_ctx; 27f05cddf9SRui Paulo u8 eap_type; 28780fb4a2SCy Schubert struct wpabuf *pending_resp; 29*a90b9d01SCy Schubert bool prot_success_received; 3039beb93cSSam Leffler }; 3139beb93cSSam Leffler 3239beb93cSSam Leffler 3339beb93cSSam Leffler static void * eap_tls_init(struct eap_sm *sm) 3439beb93cSSam Leffler { 3539beb93cSSam Leffler struct eap_tls_data *data; 3639beb93cSSam Leffler struct eap_peer_config *config = eap_get_config(sm); 37c1d255d3SCy Schubert struct eap_peer_cert_config *cert; 38c1d255d3SCy Schubert 39c1d255d3SCy Schubert if (!config) 40c1d255d3SCy Schubert return NULL; 41c1d255d3SCy Schubert if (!sm->init_phase2) 42c1d255d3SCy Schubert cert = &config->cert; 43c1d255d3SCy Schubert else if (sm->use_machine_cred) 44c1d255d3SCy Schubert cert = &config->machine_cert; 45c1d255d3SCy Schubert else 46c1d255d3SCy Schubert cert = &config->phase2_cert; 47c1d255d3SCy Schubert if (!cert->private_key && cert->engine == 0) { 4839beb93cSSam Leffler wpa_printf(MSG_INFO, "EAP-TLS: Private key not configured"); 4939beb93cSSam Leffler return NULL; 5039beb93cSSam Leffler } 5139beb93cSSam Leffler 5239beb93cSSam Leffler data = os_zalloc(sizeof(*data)); 5339beb93cSSam Leffler if (data == NULL) 5439beb93cSSam Leffler return NULL; 5539beb93cSSam Leffler 56f05cddf9SRui Paulo data->ssl_ctx = sm->init_phase2 && sm->ssl_ctx2 ? sm->ssl_ctx2 : 57f05cddf9SRui Paulo sm->ssl_ctx; 58f05cddf9SRui Paulo 59f05cddf9SRui Paulo if (eap_peer_tls_ssl_init(sm, &data->ssl, config, EAP_TYPE_TLS)) { 6039beb93cSSam Leffler wpa_printf(MSG_INFO, "EAP-TLS: Failed to initialize SSL."); 6139beb93cSSam Leffler eap_tls_deinit(sm, data); 62c1d255d3SCy Schubert if (cert->engine) { 6339beb93cSSam Leffler wpa_printf(MSG_DEBUG, "EAP-TLS: Requesting Smartcard " 6439beb93cSSam Leffler "PIN"); 6539beb93cSSam Leffler eap_sm_request_pin(sm); 66c1d255d3SCy Schubert sm->ignore = true; 67c1d255d3SCy Schubert } else if (cert->private_key && !cert->private_key_passwd) { 6839beb93cSSam Leffler wpa_printf(MSG_DEBUG, "EAP-TLS: Requesting private " 6939beb93cSSam Leffler "key passphrase"); 7039beb93cSSam Leffler eap_sm_request_passphrase(sm); 71c1d255d3SCy Schubert sm->ignore = true; 7239beb93cSSam Leffler } 7339beb93cSSam Leffler return NULL; 7439beb93cSSam Leffler } 7539beb93cSSam Leffler 76f05cddf9SRui Paulo data->eap_type = EAP_TYPE_TLS; 77f05cddf9SRui Paulo 7839beb93cSSam Leffler return data; 7939beb93cSSam Leffler } 8039beb93cSSam Leffler 8139beb93cSSam Leffler 82f05cddf9SRui Paulo #ifdef EAP_UNAUTH_TLS 83f05cddf9SRui Paulo static void * eap_unauth_tls_init(struct eap_sm *sm) 84f05cddf9SRui Paulo { 85f05cddf9SRui Paulo struct eap_tls_data *data; 86f05cddf9SRui Paulo struct eap_peer_config *config = eap_get_config(sm); 87f05cddf9SRui Paulo 88f05cddf9SRui Paulo data = os_zalloc(sizeof(*data)); 89f05cddf9SRui Paulo if (data == NULL) 90f05cddf9SRui Paulo return NULL; 91f05cddf9SRui Paulo 92f05cddf9SRui Paulo data->ssl_ctx = sm->init_phase2 && sm->ssl_ctx2 ? sm->ssl_ctx2 : 93f05cddf9SRui Paulo sm->ssl_ctx; 94f05cddf9SRui Paulo 95f05cddf9SRui Paulo if (eap_peer_tls_ssl_init(sm, &data->ssl, config, 96f05cddf9SRui Paulo EAP_UNAUTH_TLS_TYPE)) { 97f05cddf9SRui Paulo wpa_printf(MSG_INFO, "EAP-TLS: Failed to initialize SSL."); 98f05cddf9SRui Paulo eap_tls_deinit(sm, data); 99f05cddf9SRui Paulo return NULL; 100f05cddf9SRui Paulo } 101f05cddf9SRui Paulo 102f05cddf9SRui Paulo data->eap_type = EAP_UNAUTH_TLS_TYPE; 103f05cddf9SRui Paulo 104f05cddf9SRui Paulo return data; 105f05cddf9SRui Paulo } 106f05cddf9SRui Paulo #endif /* EAP_UNAUTH_TLS */ 107f05cddf9SRui Paulo 108f05cddf9SRui Paulo 1095b9c547cSRui Paulo #ifdef CONFIG_HS20 1105b9c547cSRui Paulo static void * eap_wfa_unauth_tls_init(struct eap_sm *sm) 1115b9c547cSRui Paulo { 1125b9c547cSRui Paulo struct eap_tls_data *data; 1135b9c547cSRui Paulo struct eap_peer_config *config = eap_get_config(sm); 1145b9c547cSRui Paulo 1155b9c547cSRui Paulo data = os_zalloc(sizeof(*data)); 1165b9c547cSRui Paulo if (data == NULL) 1175b9c547cSRui Paulo return NULL; 1185b9c547cSRui Paulo 1195b9c547cSRui Paulo data->ssl_ctx = sm->init_phase2 && sm->ssl_ctx2 ? sm->ssl_ctx2 : 1205b9c547cSRui Paulo sm->ssl_ctx; 1215b9c547cSRui Paulo 1225b9c547cSRui Paulo if (eap_peer_tls_ssl_init(sm, &data->ssl, config, 1235b9c547cSRui Paulo EAP_WFA_UNAUTH_TLS_TYPE)) { 1245b9c547cSRui Paulo wpa_printf(MSG_INFO, "EAP-TLS: Failed to initialize SSL."); 1255b9c547cSRui Paulo eap_tls_deinit(sm, data); 1265b9c547cSRui Paulo return NULL; 1275b9c547cSRui Paulo } 1285b9c547cSRui Paulo 1295b9c547cSRui Paulo data->eap_type = EAP_WFA_UNAUTH_TLS_TYPE; 1305b9c547cSRui Paulo 1315b9c547cSRui Paulo return data; 1325b9c547cSRui Paulo } 1335b9c547cSRui Paulo #endif /* CONFIG_HS20 */ 1345b9c547cSRui Paulo 1355b9c547cSRui Paulo 1365b9c547cSRui Paulo static void eap_tls_free_key(struct eap_tls_data *data) 1375b9c547cSRui Paulo { 1385b9c547cSRui Paulo if (data->key_data) { 1395b9c547cSRui Paulo bin_clear_free(data->key_data, EAP_TLS_KEY_LEN + EAP_EMSK_LEN); 1405b9c547cSRui Paulo data->key_data = NULL; 1415b9c547cSRui Paulo } 1425b9c547cSRui Paulo } 1435b9c547cSRui Paulo 1445b9c547cSRui Paulo 14539beb93cSSam Leffler static void eap_tls_deinit(struct eap_sm *sm, void *priv) 14639beb93cSSam Leffler { 14739beb93cSSam Leffler struct eap_tls_data *data = priv; 14839beb93cSSam Leffler if (data == NULL) 14939beb93cSSam Leffler return; 15039beb93cSSam Leffler eap_peer_tls_ssl_deinit(sm, &data->ssl); 1515b9c547cSRui Paulo eap_tls_free_key(data); 1525b9c547cSRui Paulo os_free(data->session_id); 153780fb4a2SCy Schubert wpabuf_free(data->pending_resp); 15439beb93cSSam Leffler os_free(data); 15539beb93cSSam Leffler } 15639beb93cSSam Leffler 15739beb93cSSam Leffler 15839beb93cSSam Leffler static struct wpabuf * eap_tls_failure(struct eap_sm *sm, 15939beb93cSSam Leffler struct eap_tls_data *data, 16039beb93cSSam Leffler struct eap_method_ret *ret, int res, 16139beb93cSSam Leffler struct wpabuf *resp, u8 id) 16239beb93cSSam Leffler { 16339beb93cSSam Leffler wpa_printf(MSG_DEBUG, "EAP-TLS: TLS processing failed"); 16439beb93cSSam Leffler 16539beb93cSSam Leffler ret->methodState = METHOD_DONE; 16639beb93cSSam Leffler ret->decision = DECISION_FAIL; 16739beb93cSSam Leffler 16839beb93cSSam Leffler if (resp) { 16939beb93cSSam Leffler /* 17039beb93cSSam Leffler * This is likely an alert message, so send it instead of just 17139beb93cSSam Leffler * ACKing the error. 17239beb93cSSam Leffler */ 17339beb93cSSam Leffler return resp; 17439beb93cSSam Leffler } 17539beb93cSSam Leffler 176f05cddf9SRui Paulo return eap_peer_tls_build_ack(id, data->eap_type, 0); 17739beb93cSSam Leffler } 17839beb93cSSam Leffler 17939beb93cSSam Leffler 18039beb93cSSam Leffler static void eap_tls_success(struct eap_sm *sm, struct eap_tls_data *data, 18139beb93cSSam Leffler struct eap_method_ret *ret) 18239beb93cSSam Leffler { 18385732ac8SCy Schubert const char *label; 184206b73d0SCy Schubert const u8 eap_tls13_context[] = { EAP_TYPE_TLS }; 185206b73d0SCy Schubert const u8 *context = NULL; 186206b73d0SCy Schubert size_t context_len = 0; 18785732ac8SCy Schubert 18839beb93cSSam Leffler wpa_printf(MSG_DEBUG, "EAP-TLS: Done"); 18939beb93cSSam Leffler 19085732ac8SCy Schubert if (data->ssl.tls_out) { 19185732ac8SCy Schubert wpa_printf(MSG_DEBUG, "EAP-TLS: Fragment(s) remaining"); 19285732ac8SCy Schubert return; 19385732ac8SCy Schubert } 19485732ac8SCy Schubert 19585732ac8SCy Schubert if (data->ssl.tls_v13) { 19685732ac8SCy Schubert label = "EXPORTER_EAP_TLS_Key_Material"; 197206b73d0SCy Schubert context = eap_tls13_context; 198206b73d0SCy Schubert context_len = 1; 19985732ac8SCy Schubert 20085732ac8SCy Schubert /* A possible NewSessionTicket may be received before 20185732ac8SCy Schubert * EAP-Success, so need to allow it to be received. */ 20285732ac8SCy Schubert ret->methodState = METHOD_MAY_CONT; 20385732ac8SCy Schubert ret->decision = DECISION_COND_SUCC; 20485732ac8SCy Schubert } else { 20585732ac8SCy Schubert label = "client EAP encryption"; 20685732ac8SCy Schubert 20739beb93cSSam Leffler ret->methodState = METHOD_DONE; 20839beb93cSSam Leffler ret->decision = DECISION_UNCOND_SUCC; 20985732ac8SCy Schubert } 21039beb93cSSam Leffler 2115b9c547cSRui Paulo eap_tls_free_key(data); 21285732ac8SCy Schubert data->key_data = eap_peer_tls_derive_key(sm, &data->ssl, label, 213206b73d0SCy Schubert context, context_len, 21439beb93cSSam Leffler EAP_TLS_KEY_LEN + 21539beb93cSSam Leffler EAP_EMSK_LEN); 21639beb93cSSam Leffler if (data->key_data) { 21739beb93cSSam Leffler wpa_hexdump_key(MSG_DEBUG, "EAP-TLS: Derived key", 21839beb93cSSam Leffler data->key_data, EAP_TLS_KEY_LEN); 21939beb93cSSam Leffler wpa_hexdump_key(MSG_DEBUG, "EAP-TLS: Derived EMSK", 22039beb93cSSam Leffler data->key_data + EAP_TLS_KEY_LEN, 22139beb93cSSam Leffler EAP_EMSK_LEN); 22239beb93cSSam Leffler } else { 22339beb93cSSam Leffler wpa_printf(MSG_INFO, "EAP-TLS: Failed to derive key"); 22439beb93cSSam Leffler } 2255b9c547cSRui Paulo 2265b9c547cSRui Paulo os_free(data->session_id); 2275b9c547cSRui Paulo data->session_id = eap_peer_tls_derive_session_id(sm, &data->ssl, 2285b9c547cSRui Paulo EAP_TYPE_TLS, 2295b9c547cSRui Paulo &data->id_len); 2305b9c547cSRui Paulo if (data->session_id) { 2315b9c547cSRui Paulo wpa_hexdump(MSG_DEBUG, "EAP-TLS: Derived Session-Id", 2325b9c547cSRui Paulo data->session_id, data->id_len); 2335b9c547cSRui Paulo } else { 2345b9c547cSRui Paulo wpa_printf(MSG_ERROR, "EAP-TLS: Failed to derive Session-Id"); 2355b9c547cSRui Paulo } 23639beb93cSSam Leffler } 23739beb93cSSam Leffler 23839beb93cSSam Leffler 23939beb93cSSam Leffler static struct wpabuf * eap_tls_process(struct eap_sm *sm, void *priv, 24039beb93cSSam Leffler struct eap_method_ret *ret, 24139beb93cSSam Leffler const struct wpabuf *reqData) 24239beb93cSSam Leffler { 24339beb93cSSam Leffler size_t left; 24439beb93cSSam Leffler int res; 24539beb93cSSam Leffler struct wpabuf *resp; 24639beb93cSSam Leffler u8 flags, id; 24739beb93cSSam Leffler const u8 *pos; 24839beb93cSSam Leffler struct eap_tls_data *data = priv; 249325151a3SRui Paulo struct wpabuf msg; 25039beb93cSSam Leffler 251780fb4a2SCy Schubert if (sm->waiting_ext_cert_check && data->pending_resp) { 252780fb4a2SCy Schubert struct eap_peer_config *config = eap_get_config(sm); 253780fb4a2SCy Schubert 254780fb4a2SCy Schubert if (config->pending_ext_cert_check == EXT_CERT_CHECK_GOOD) { 255780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, 256780fb4a2SCy Schubert "EAP-TLS: External certificate check succeeded - continue handshake"); 257780fb4a2SCy Schubert resp = data->pending_resp; 258780fb4a2SCy Schubert data->pending_resp = NULL; 259780fb4a2SCy Schubert sm->waiting_ext_cert_check = 0; 260780fb4a2SCy Schubert return resp; 261780fb4a2SCy Schubert } 262780fb4a2SCy Schubert 263780fb4a2SCy Schubert if (config->pending_ext_cert_check == EXT_CERT_CHECK_BAD) { 264780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, 265780fb4a2SCy Schubert "EAP-TLS: External certificate check failed - force authentication failure"); 266780fb4a2SCy Schubert ret->methodState = METHOD_DONE; 267780fb4a2SCy Schubert ret->decision = DECISION_FAIL; 268780fb4a2SCy Schubert sm->waiting_ext_cert_check = 0; 269780fb4a2SCy Schubert return NULL; 270780fb4a2SCy Schubert } 271780fb4a2SCy Schubert 272780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, 273780fb4a2SCy Schubert "EAP-TLS: Continuing to wait external server certificate validation"); 274780fb4a2SCy Schubert return NULL; 275780fb4a2SCy Schubert } 276780fb4a2SCy Schubert 277f05cddf9SRui Paulo pos = eap_peer_tls_process_init(sm, &data->ssl, data->eap_type, ret, 27839beb93cSSam Leffler reqData, &left, &flags); 27939beb93cSSam Leffler if (pos == NULL) 28039beb93cSSam Leffler return NULL; 28139beb93cSSam Leffler id = eap_get_id(reqData); 28239beb93cSSam Leffler 28339beb93cSSam Leffler if (flags & EAP_TLS_FLAGS_START) { 28439beb93cSSam Leffler wpa_printf(MSG_DEBUG, "EAP-TLS: Start"); 28539beb93cSSam Leffler left = 0; /* make sure that this frame is empty, even though it 28639beb93cSSam Leffler * should always be, anyway */ 28739beb93cSSam Leffler } 28839beb93cSSam Leffler 28939beb93cSSam Leffler resp = NULL; 290325151a3SRui Paulo wpabuf_set(&msg, pos, left); 291f05cddf9SRui Paulo res = eap_peer_tls_process_helper(sm, &data->ssl, data->eap_type, 0, 292325151a3SRui Paulo id, &msg, &resp); 29339beb93cSSam Leffler 29439beb93cSSam Leffler if (res < 0) { 29539beb93cSSam Leffler return eap_tls_failure(sm, data, ret, res, resp, id); 29639beb93cSSam Leffler } 29739beb93cSSam Leffler 298780fb4a2SCy Schubert if (sm->waiting_ext_cert_check) { 299780fb4a2SCy Schubert wpa_printf(MSG_DEBUG, 300780fb4a2SCy Schubert "EAP-TLS: Waiting external server certificate validation"); 301780fb4a2SCy Schubert wpabuf_free(data->pending_resp); 302780fb4a2SCy Schubert data->pending_resp = resp; 303780fb4a2SCy Schubert return NULL; 304780fb4a2SCy Schubert } 305780fb4a2SCy Schubert 306*a90b9d01SCy Schubert /* RFC 9190 Section 2.5 */ 307c1d255d3SCy Schubert if (res == 2 && data->ssl.tls_v13 && wpabuf_len(resp) == 1 && 308c1d255d3SCy Schubert *wpabuf_head_u8(resp) == 0) { 309*a90b9d01SCy Schubert wpa_printf(MSG_DEBUG, 310*a90b9d01SCy Schubert "EAP-TLS: ACKing protected success indication (appl data 0x00)"); 311206b73d0SCy Schubert eap_peer_tls_reset_output(&data->ssl); 312206b73d0SCy Schubert res = 1; 313*a90b9d01SCy Schubert ret->methodState = METHOD_DONE; 314*a90b9d01SCy Schubert ret->decision = DECISION_UNCOND_SUCC; 315*a90b9d01SCy Schubert data->prot_success_received = true; 316206b73d0SCy Schubert } 317206b73d0SCy Schubert 318*a90b9d01SCy Schubert if (tls_connection_established(data->ssl_ctx, data->ssl.conn) && 319*a90b9d01SCy Schubert (!data->ssl.tls_v13 || data->prot_success_received)) 32039beb93cSSam Leffler eap_tls_success(sm, data, ret); 32139beb93cSSam Leffler 32239beb93cSSam Leffler if (res == 1) { 32339beb93cSSam Leffler wpabuf_free(resp); 324f05cddf9SRui Paulo return eap_peer_tls_build_ack(id, data->eap_type, 0); 32539beb93cSSam Leffler } 32639beb93cSSam Leffler 32739beb93cSSam Leffler return resp; 32839beb93cSSam Leffler } 32939beb93cSSam Leffler 33039beb93cSSam Leffler 331c1d255d3SCy Schubert static bool eap_tls_has_reauth_data(struct eap_sm *sm, void *priv) 33239beb93cSSam Leffler { 33339beb93cSSam Leffler struct eap_tls_data *data = priv; 334f05cddf9SRui Paulo return tls_connection_established(data->ssl_ctx, data->ssl.conn); 33539beb93cSSam Leffler } 33639beb93cSSam Leffler 33739beb93cSSam Leffler 33839beb93cSSam Leffler static void eap_tls_deinit_for_reauth(struct eap_sm *sm, void *priv) 33939beb93cSSam Leffler { 340780fb4a2SCy Schubert struct eap_tls_data *data = priv; 341780fb4a2SCy Schubert 342780fb4a2SCy Schubert wpabuf_free(data->pending_resp); 343780fb4a2SCy Schubert data->pending_resp = NULL; 344*a90b9d01SCy Schubert data->prot_success_received = false; 34539beb93cSSam Leffler } 34639beb93cSSam Leffler 34739beb93cSSam Leffler 34839beb93cSSam Leffler static void * eap_tls_init_for_reauth(struct eap_sm *sm, void *priv) 34939beb93cSSam Leffler { 35039beb93cSSam Leffler struct eap_tls_data *data = priv; 3515b9c547cSRui Paulo eap_tls_free_key(data); 3525b9c547cSRui Paulo os_free(data->session_id); 3535b9c547cSRui Paulo data->session_id = NULL; 35439beb93cSSam Leffler if (eap_peer_tls_reauth_init(sm, &data->ssl)) { 35539beb93cSSam Leffler os_free(data); 35639beb93cSSam Leffler return NULL; 35739beb93cSSam Leffler } 35839beb93cSSam Leffler return priv; 35939beb93cSSam Leffler } 36039beb93cSSam Leffler 36139beb93cSSam Leffler 36239beb93cSSam Leffler static int eap_tls_get_status(struct eap_sm *sm, void *priv, char *buf, 36339beb93cSSam Leffler size_t buflen, int verbose) 36439beb93cSSam Leffler { 36539beb93cSSam Leffler struct eap_tls_data *data = priv; 36639beb93cSSam Leffler return eap_peer_tls_status(sm, &data->ssl, buf, buflen, verbose); 36739beb93cSSam Leffler } 36839beb93cSSam Leffler 36939beb93cSSam Leffler 370c1d255d3SCy Schubert static bool eap_tls_isKeyAvailable(struct eap_sm *sm, void *priv) 37139beb93cSSam Leffler { 37239beb93cSSam Leffler struct eap_tls_data *data = priv; 37339beb93cSSam Leffler return data->key_data != NULL; 37439beb93cSSam Leffler } 37539beb93cSSam Leffler 37639beb93cSSam Leffler 37739beb93cSSam Leffler static u8 * eap_tls_getKey(struct eap_sm *sm, void *priv, size_t *len) 37839beb93cSSam Leffler { 37939beb93cSSam Leffler struct eap_tls_data *data = priv; 38039beb93cSSam Leffler u8 *key; 38139beb93cSSam Leffler 38239beb93cSSam Leffler if (data->key_data == NULL) 38339beb93cSSam Leffler return NULL; 38439beb93cSSam Leffler 38585732ac8SCy Schubert key = os_memdup(data->key_data, EAP_TLS_KEY_LEN); 38639beb93cSSam Leffler if (key == NULL) 38739beb93cSSam Leffler return NULL; 38839beb93cSSam Leffler 38939beb93cSSam Leffler *len = EAP_TLS_KEY_LEN; 39039beb93cSSam Leffler 39139beb93cSSam Leffler return key; 39239beb93cSSam Leffler } 39339beb93cSSam Leffler 39439beb93cSSam Leffler 39539beb93cSSam Leffler static u8 * eap_tls_get_emsk(struct eap_sm *sm, void *priv, size_t *len) 39639beb93cSSam Leffler { 39739beb93cSSam Leffler struct eap_tls_data *data = priv; 39839beb93cSSam Leffler u8 *key; 39939beb93cSSam Leffler 40039beb93cSSam Leffler if (data->key_data == NULL) 40139beb93cSSam Leffler return NULL; 40239beb93cSSam Leffler 40385732ac8SCy Schubert key = os_memdup(data->key_data + EAP_TLS_KEY_LEN, EAP_EMSK_LEN); 40439beb93cSSam Leffler if (key == NULL) 40539beb93cSSam Leffler return NULL; 40639beb93cSSam Leffler 40739beb93cSSam Leffler *len = EAP_EMSK_LEN; 40839beb93cSSam Leffler 40939beb93cSSam Leffler return key; 41039beb93cSSam Leffler } 41139beb93cSSam Leffler 41239beb93cSSam Leffler 4135b9c547cSRui Paulo static u8 * eap_tls_get_session_id(struct eap_sm *sm, void *priv, size_t *len) 4145b9c547cSRui Paulo { 4155b9c547cSRui Paulo struct eap_tls_data *data = priv; 4165b9c547cSRui Paulo u8 *id; 4175b9c547cSRui Paulo 4185b9c547cSRui Paulo if (data->session_id == NULL) 4195b9c547cSRui Paulo return NULL; 4205b9c547cSRui Paulo 42185732ac8SCy Schubert id = os_memdup(data->session_id, data->id_len); 4225b9c547cSRui Paulo if (id == NULL) 4235b9c547cSRui Paulo return NULL; 4245b9c547cSRui Paulo 4255b9c547cSRui Paulo *len = data->id_len; 4265b9c547cSRui Paulo 4275b9c547cSRui Paulo return id; 4285b9c547cSRui Paulo } 4295b9c547cSRui Paulo 4305b9c547cSRui Paulo 43139beb93cSSam Leffler int eap_peer_tls_register(void) 43239beb93cSSam Leffler { 43339beb93cSSam Leffler struct eap_method *eap; 43439beb93cSSam Leffler 43539beb93cSSam Leffler eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION, 43639beb93cSSam Leffler EAP_VENDOR_IETF, EAP_TYPE_TLS, "TLS"); 43739beb93cSSam Leffler if (eap == NULL) 43839beb93cSSam Leffler return -1; 43939beb93cSSam Leffler 44039beb93cSSam Leffler eap->init = eap_tls_init; 44139beb93cSSam Leffler eap->deinit = eap_tls_deinit; 44239beb93cSSam Leffler eap->process = eap_tls_process; 44339beb93cSSam Leffler eap->isKeyAvailable = eap_tls_isKeyAvailable; 44439beb93cSSam Leffler eap->getKey = eap_tls_getKey; 4455b9c547cSRui Paulo eap->getSessionId = eap_tls_get_session_id; 44639beb93cSSam Leffler eap->get_status = eap_tls_get_status; 44739beb93cSSam Leffler eap->has_reauth_data = eap_tls_has_reauth_data; 44839beb93cSSam Leffler eap->deinit_for_reauth = eap_tls_deinit_for_reauth; 44939beb93cSSam Leffler eap->init_for_reauth = eap_tls_init_for_reauth; 45039beb93cSSam Leffler eap->get_emsk = eap_tls_get_emsk; 45139beb93cSSam Leffler 452780fb4a2SCy Schubert return eap_peer_method_register(eap); 45339beb93cSSam Leffler } 454f05cddf9SRui Paulo 455f05cddf9SRui Paulo 456f05cddf9SRui Paulo #ifdef EAP_UNAUTH_TLS 457f05cddf9SRui Paulo int eap_peer_unauth_tls_register(void) 458f05cddf9SRui Paulo { 459f05cddf9SRui Paulo struct eap_method *eap; 460f05cddf9SRui Paulo 461f05cddf9SRui Paulo eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION, 462f05cddf9SRui Paulo EAP_VENDOR_UNAUTH_TLS, 463f05cddf9SRui Paulo EAP_VENDOR_TYPE_UNAUTH_TLS, "UNAUTH-TLS"); 464f05cddf9SRui Paulo if (eap == NULL) 465f05cddf9SRui Paulo return -1; 466f05cddf9SRui Paulo 467f05cddf9SRui Paulo eap->init = eap_unauth_tls_init; 468f05cddf9SRui Paulo eap->deinit = eap_tls_deinit; 469f05cddf9SRui Paulo eap->process = eap_tls_process; 470f05cddf9SRui Paulo eap->isKeyAvailable = eap_tls_isKeyAvailable; 471f05cddf9SRui Paulo eap->getKey = eap_tls_getKey; 472f05cddf9SRui Paulo eap->get_status = eap_tls_get_status; 473f05cddf9SRui Paulo eap->has_reauth_data = eap_tls_has_reauth_data; 474f05cddf9SRui Paulo eap->deinit_for_reauth = eap_tls_deinit_for_reauth; 475f05cddf9SRui Paulo eap->init_for_reauth = eap_tls_init_for_reauth; 476f05cddf9SRui Paulo eap->get_emsk = eap_tls_get_emsk; 477f05cddf9SRui Paulo 478780fb4a2SCy Schubert return eap_peer_method_register(eap); 479f05cddf9SRui Paulo } 480f05cddf9SRui Paulo #endif /* EAP_UNAUTH_TLS */ 4815b9c547cSRui Paulo 4825b9c547cSRui Paulo 4835b9c547cSRui Paulo #ifdef CONFIG_HS20 4845b9c547cSRui Paulo int eap_peer_wfa_unauth_tls_register(void) 4855b9c547cSRui Paulo { 4865b9c547cSRui Paulo struct eap_method *eap; 4875b9c547cSRui Paulo 4885b9c547cSRui Paulo eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION, 4895b9c547cSRui Paulo EAP_VENDOR_WFA_NEW, 4905b9c547cSRui Paulo EAP_VENDOR_WFA_UNAUTH_TLS, 4915b9c547cSRui Paulo "WFA-UNAUTH-TLS"); 4925b9c547cSRui Paulo if (eap == NULL) 4935b9c547cSRui Paulo return -1; 4945b9c547cSRui Paulo 4955b9c547cSRui Paulo eap->init = eap_wfa_unauth_tls_init; 4965b9c547cSRui Paulo eap->deinit = eap_tls_deinit; 4975b9c547cSRui Paulo eap->process = eap_tls_process; 4985b9c547cSRui Paulo eap->isKeyAvailable = eap_tls_isKeyAvailable; 4995b9c547cSRui Paulo eap->getKey = eap_tls_getKey; 5005b9c547cSRui Paulo eap->get_status = eap_tls_get_status; 5015b9c547cSRui Paulo eap->has_reauth_data = eap_tls_has_reauth_data; 5025b9c547cSRui Paulo eap->deinit_for_reauth = eap_tls_deinit_for_reauth; 5035b9c547cSRui Paulo eap->init_for_reauth = eap_tls_init_for_reauth; 5045b9c547cSRui Paulo eap->get_emsk = eap_tls_get_emsk; 5055b9c547cSRui Paulo 506780fb4a2SCy Schubert return eap_peer_method_register(eap); 5075b9c547cSRui Paulo } 5085b9c547cSRui Paulo #endif /* CONFIG_HS20 */ 509