18d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt/* 28d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * EAP peer method: EAP-TLS (RFC 2716) 38d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * Copyright (c) 2004-2008, 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/tls.h" 138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_i.h" 148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_tls_common.h" 158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt#include "eap_config.h" 168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_tls_deinit(struct eap_sm *sm, void *priv); 198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstruct eap_tls_data { 228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_ssl_data ssl; 238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *key_data; 248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt}; 258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void * eap_tls_init(struct eap_sm *sm) 288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_tls_data *data; 308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config = eap_get_config(sm); 318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config == NULL || 328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ((sm->init_phase2 ? config->private_key2 : config->private_key) 338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt == NULL && 348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt (sm->init_phase2 ? config->engine2 : config->engine) == 0)) { 358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "EAP-TLS: Private key not configured"); 368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data = os_zalloc(sizeof(*data)); 408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data == NULL) 418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_peer_tls_ssl_init(sm, &data->ssl, config)) { 448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "EAP-TLS: Failed to initialize SSL."); 458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_tls_deinit(sm, data); 468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config->engine) { 478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TLS: Requesting Smartcard " 488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "PIN"); 498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_request_pin(sm); 508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ignore = TRUE; 518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else if (config->private_key && !config->private_key_passwd) 528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt { 538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TLS: Requesting private " 548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "key passphrase"); 558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_sm_request_passphrase(sm); 568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt sm->ignore = TRUE; 578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return data; 628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_tls_deinit(struct eap_sm *sm, void *priv) 668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_tls_data *data = priv; 688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data == NULL) 698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return; 708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_peer_tls_ssl_deinit(sm, &data->ssl); 718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data->key_data); 728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data); 738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eap_tls_failure(struct eap_sm *sm, 778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_tls_data *data, 788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method_ret *ret, int res, 798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp, u8 id) 808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TLS: TLS processing failed"); 828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->methodState = METHOD_DONE; 848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->decision = DECISION_FAIL; 858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == -1) { 878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_peer_config *config = eap_get_config(sm); 888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (config) { 898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * The TLS handshake failed. So better forget the old 918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * PIN. It may be wrong, we cannot be sure but trying 928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * the wrong one again might block it on the card--so 938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * better ask the user again. 948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(config->pin); 968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt config->pin = NULL; 978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (resp) { 1018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt /* 1028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * This is likely an alert message, so send it instead of just 1038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * ACKing the error. 1048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt */ 1058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 1068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eap_peer_tls_build_ack(id, EAP_TYPE_TLS, 0); 1098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_tls_success(struct eap_sm *sm, struct eap_tls_data *data, 1138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method_ret *ret) 1148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TLS: Done"); 1168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->methodState = METHOD_DONE; 1188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret->decision = DECISION_UNCOND_SUCC; 1198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data->key_data); 1218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->key_data = eap_peer_tls_derive_key(sm, &data->ssl, 1228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt "client EAP encryption", 1238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_TLS_KEY_LEN + 1248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_EMSK_LEN); 1258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->key_data) { 1268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "EAP-TLS: Derived key", 1278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->key_data, EAP_TLS_KEY_LEN); 1288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_hexdump_key(MSG_DEBUG, "EAP-TLS: Derived EMSK", 1298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->key_data + EAP_TLS_KEY_LEN, 1308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_EMSK_LEN); 1318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } else { 1328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_INFO, "EAP-TLS: Failed to derive key"); 1338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic struct wpabuf * eap_tls_process(struct eap_sm *sm, void *priv, 1388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method_ret *ret, 1398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const struct wpabuf *reqData) 1408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t left; 1428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int res; 1438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct wpabuf *resp; 1448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 flags, id; 1458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt const u8 *pos; 1468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_tls_data *data = priv; 1478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos = eap_peer_tls_process_init(sm, &data->ssl, EAP_TYPE_TLS, ret, 1498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt reqData, &left, &flags); 1508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (pos == NULL) 1518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 1528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt id = eap_get_id(reqData); 1538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (flags & EAP_TLS_FLAGS_START) { 1558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpa_printf(MSG_DEBUG, "EAP-TLS: Start"); 1568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt left = 0; /* make sure that this frame is empty, even though it 1578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt * should always be, anyway */ 1588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt resp = NULL; 1618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt res = eap_peer_tls_process_helper(sm, &data->ssl, EAP_TYPE_TLS, 0, id, 1628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt pos, left, &resp); 1638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res < 0) { 1658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eap_tls_failure(sm, data, ret, res, resp, id); 1668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) 1698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_tls_success(sm, data, ret); 1708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (res == 1) { 1728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt wpabuf_free(resp); 1738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eap_peer_tls_build_ack(id, EAP_TYPE_TLS, 0); 1748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 1758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return resp; 1778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic Boolean eap_tls_has_reauth_data(struct eap_sm *sm, void *priv) 1818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_tls_data *data = priv; 1838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return tls_connection_established(sm->ssl_ctx, data->ssl.conn); 1848d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1858d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1868d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1878d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void eap_tls_deinit_for_reauth(struct eap_sm *sm, void *priv) 1888d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1898d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 1908d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1918d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 1928d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic void * eap_tls_init_for_reauth(struct eap_sm *sm, void *priv) 1938d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 1948d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_tls_data *data = priv; 1958d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data->key_data); 1968d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt data->key_data = NULL; 1978d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap_peer_tls_reauth_init(sm, &data->ssl)) { 1988d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_free(data); 1998d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2008d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt } 2018d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return priv; 2028d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2038d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2048d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2058d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic int eap_tls_get_status(struct eap_sm *sm, void *priv, char *buf, 2068d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt size_t buflen, int verbose) 2078d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2088d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_tls_data *data = priv; 2098d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return eap_peer_tls_status(sm, &data->ssl, buf, buflen, verbose); 2108d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2118d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2128d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2138d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic Boolean eap_tls_isKeyAvailable(struct eap_sm *sm, void *priv) 2148d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2158d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_tls_data *data = priv; 2168d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return data->key_data != NULL; 2178d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2188d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2198d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2208d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u8 * eap_tls_getKey(struct eap_sm *sm, void *priv, size_t *len) 2218d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2228d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_tls_data *data = priv; 2238d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *key; 2248d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2258d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->key_data == NULL) 2268d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2278d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2288d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key = os_malloc(EAP_TLS_KEY_LEN); 2298d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key == NULL) 2308d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2318d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2328d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = EAP_TLS_KEY_LEN; 2338d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(key, data->key_data, EAP_TLS_KEY_LEN); 2348d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2358d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return key; 2368d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2378d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2388d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2398d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtstatic u8 * eap_tls_get_emsk(struct eap_sm *sm, void *priv, size_t *len) 2408d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2418d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_tls_data *data = priv; 2428d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt u8 *key; 2438d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2448d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (data->key_data == NULL) 2458d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2468d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2478d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt key = os_malloc(EAP_EMSK_LEN); 2488d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (key == NULL) 2498d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return NULL; 2508d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2518d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt *len = EAP_EMSK_LEN; 2528d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt os_memcpy(key, data->key_data + EAP_TLS_KEY_LEN, EAP_EMSK_LEN); 2538d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2548d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return key; 2558d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 2568d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2578d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2588d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidtint eap_peer_tls_register(void) 2598d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt{ 2608d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt struct eap_method *eap; 2618d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt int ret; 2628d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2638d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap = eap_peer_method_alloc(EAP_PEER_METHOD_INTERFACE_VERSION, 2648d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt EAP_VENDOR_IETF, EAP_TYPE_TLS, "TLS"); 2658d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (eap == NULL) 2668d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return -1; 2678d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2688d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->init = eap_tls_init; 2698d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->deinit = eap_tls_deinit; 2708d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->process = eap_tls_process; 2718d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->isKeyAvailable = eap_tls_isKeyAvailable; 2728d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->getKey = eap_tls_getKey; 2738d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->get_status = eap_tls_get_status; 2748d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->has_reauth_data = eap_tls_has_reauth_data; 2758d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->deinit_for_reauth = eap_tls_deinit_for_reauth; 2768d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->init_for_reauth = eap_tls_init_for_reauth; 2778d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap->get_emsk = eap_tls_get_emsk; 2788d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt 2798d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt ret = eap_peer_method_register(eap); 2808d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt if (ret) 2818d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt eap_peer_method_free(eap); 2828d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt return ret; 2838d520ff1dc2da35cdca849e982051b86468016d8Dmitry Shmidt} 284