eap_server_ttls.c 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207
  1. /*
  2. * hostapd / EAP-TTLS (RFC 5281)
  3. * Copyright (c) 2004-2011, Jouni Malinen <j@w1.fi>
  4. *
  5. * This software may be distributed under the terms of the BSD license.
  6. * See README for more details.
  7. */
  8. #include "includes.h"
  9. #include "common.h"
  10. #include "crypto/ms_funcs.h"
  11. #include "crypto/sha1.h"
  12. #include "crypto/tls.h"
  13. #include "eap_server/eap_i.h"
  14. #include "eap_server/eap_tls_common.h"
  15. #include "eap_common/chap.h"
  16. #include "eap_common/eap_ttls.h"
  17. #define EAP_TTLS_VERSION 0
  18. static void eap_ttls_reset(struct eap_sm *sm, void *priv);
  19. struct eap_ttls_data {
  20. struct eap_ssl_data ssl;
  21. enum {
  22. START, PHASE1, PHASE2_START, PHASE2_METHOD,
  23. PHASE2_MSCHAPV2_RESP, SUCCESS, FAILURE
  24. } state;
  25. int ttls_version;
  26. const struct eap_method *phase2_method;
  27. void *phase2_priv;
  28. int mschapv2_resp_ok;
  29. u8 mschapv2_auth_response[20];
  30. u8 mschapv2_ident;
  31. struct wpabuf *pending_phase2_eap_resp;
  32. int tnc_started;
  33. };
  34. static const char * eap_ttls_state_txt(int state)
  35. {
  36. switch (state) {
  37. case START:
  38. return "START";
  39. case PHASE1:
  40. return "PHASE1";
  41. case PHASE2_START:
  42. return "PHASE2_START";
  43. case PHASE2_METHOD:
  44. return "PHASE2_METHOD";
  45. case PHASE2_MSCHAPV2_RESP:
  46. return "PHASE2_MSCHAPV2_RESP";
  47. case SUCCESS:
  48. return "SUCCESS";
  49. case FAILURE:
  50. return "FAILURE";
  51. default:
  52. return "Unknown?!";
  53. }
  54. }
  55. static void eap_ttls_state(struct eap_ttls_data *data, int state)
  56. {
  57. wpa_printf(MSG_DEBUG, "EAP-TTLS: %s -> %s",
  58. eap_ttls_state_txt(data->state),
  59. eap_ttls_state_txt(state));
  60. data->state = state;
  61. }
  62. static u8 * eap_ttls_avp_hdr(u8 *avphdr, u32 avp_code, u32 vendor_id,
  63. int mandatory, size_t len)
  64. {
  65. struct ttls_avp_vendor *avp;
  66. u8 flags;
  67. size_t hdrlen;
  68. avp = (struct ttls_avp_vendor *) avphdr;
  69. flags = mandatory ? AVP_FLAGS_MANDATORY : 0;
  70. if (vendor_id) {
  71. flags |= AVP_FLAGS_VENDOR;
  72. hdrlen = sizeof(*avp);
  73. avp->vendor_id = host_to_be32(vendor_id);
  74. } else {
  75. hdrlen = sizeof(struct ttls_avp);
  76. }
  77. avp->avp_code = host_to_be32(avp_code);
  78. avp->avp_length = host_to_be32(((u32) flags << 24) |
  79. ((u32) (hdrlen + len)));
  80. return avphdr + hdrlen;
  81. }
  82. static struct wpabuf * eap_ttls_avp_encapsulate(struct wpabuf *resp,
  83. u32 avp_code, int mandatory)
  84. {
  85. struct wpabuf *avp;
  86. u8 *pos;
  87. avp = wpabuf_alloc(sizeof(struct ttls_avp) + wpabuf_len(resp) + 4);
  88. if (avp == NULL) {
  89. wpabuf_free(resp);
  90. return NULL;
  91. }
  92. pos = eap_ttls_avp_hdr(wpabuf_mhead(avp), avp_code, 0, mandatory,
  93. wpabuf_len(resp));
  94. os_memcpy(pos, wpabuf_head(resp), wpabuf_len(resp));
  95. pos += wpabuf_len(resp);
  96. AVP_PAD((const u8 *) wpabuf_head(avp), pos);
  97. wpabuf_free(resp);
  98. wpabuf_put(avp, pos - (u8 *) wpabuf_head(avp));
  99. return avp;
  100. }
  101. struct eap_ttls_avp {
  102. /* Note: eap is allocated memory; caller is responsible for freeing
  103. * it. All the other pointers are pointing to the packet data, i.e.,
  104. * they must not be freed separately. */
  105. u8 *eap;
  106. size_t eap_len;
  107. u8 *user_name;
  108. size_t user_name_len;
  109. u8 *user_password;
  110. size_t user_password_len;
  111. u8 *chap_challenge;
  112. size_t chap_challenge_len;
  113. u8 *chap_password;
  114. size_t chap_password_len;
  115. u8 *mschap_challenge;
  116. size_t mschap_challenge_len;
  117. u8 *mschap_response;
  118. size_t mschap_response_len;
  119. u8 *mschap2_response;
  120. size_t mschap2_response_len;
  121. };
  122. static int eap_ttls_avp_parse(struct wpabuf *buf, struct eap_ttls_avp *parse)
  123. {
  124. struct ttls_avp *avp;
  125. u8 *pos;
  126. int left;
  127. pos = wpabuf_mhead(buf);
  128. left = wpabuf_len(buf);
  129. os_memset(parse, 0, sizeof(*parse));
  130. while (left > 0) {
  131. u32 avp_code, avp_length, vendor_id = 0;
  132. u8 avp_flags, *dpos;
  133. size_t pad, dlen;
  134. avp = (struct ttls_avp *) pos;
  135. avp_code = be_to_host32(avp->avp_code);
  136. avp_length = be_to_host32(avp->avp_length);
  137. avp_flags = (avp_length >> 24) & 0xff;
  138. avp_length &= 0xffffff;
  139. wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP: code=%d flags=0x%02x "
  140. "length=%d", (int) avp_code, avp_flags,
  141. (int) avp_length);
  142. if ((int) avp_length > left) {
  143. wpa_printf(MSG_WARNING, "EAP-TTLS: AVP overflow "
  144. "(len=%d, left=%d) - dropped",
  145. (int) avp_length, left);
  146. goto fail;
  147. }
  148. if (avp_length < sizeof(*avp)) {
  149. wpa_printf(MSG_WARNING, "EAP-TTLS: Invalid AVP length "
  150. "%d", avp_length);
  151. goto fail;
  152. }
  153. dpos = (u8 *) (avp + 1);
  154. dlen = avp_length - sizeof(*avp);
  155. if (avp_flags & AVP_FLAGS_VENDOR) {
  156. if (dlen < 4) {
  157. wpa_printf(MSG_WARNING, "EAP-TTLS: vendor AVP "
  158. "underflow");
  159. goto fail;
  160. }
  161. vendor_id = be_to_host32(* (be32 *) dpos);
  162. wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP vendor_id %d",
  163. (int) vendor_id);
  164. dpos += 4;
  165. dlen -= 4;
  166. }
  167. wpa_hexdump(MSG_DEBUG, "EAP-TTLS: AVP data", dpos, dlen);
  168. if (vendor_id == 0 && avp_code == RADIUS_ATTR_EAP_MESSAGE) {
  169. wpa_printf(MSG_DEBUG, "EAP-TTLS: AVP - EAP Message");
  170. if (parse->eap == NULL) {
  171. parse->eap = os_malloc(dlen);
  172. if (parse->eap == NULL) {
  173. wpa_printf(MSG_WARNING, "EAP-TTLS: "
  174. "failed to allocate memory "
  175. "for Phase 2 EAP data");
  176. goto fail;
  177. }
  178. os_memcpy(parse->eap, dpos, dlen);
  179. parse->eap_len = dlen;
  180. } else {
  181. u8 *neweap = os_realloc(parse->eap,
  182. parse->eap_len + dlen);
  183. if (neweap == NULL) {
  184. wpa_printf(MSG_WARNING, "EAP-TTLS: "
  185. "failed to allocate memory "
  186. "for Phase 2 EAP data");
  187. goto fail;
  188. }
  189. os_memcpy(neweap + parse->eap_len, dpos, dlen);
  190. parse->eap = neweap;
  191. parse->eap_len += dlen;
  192. }
  193. } else if (vendor_id == 0 &&
  194. avp_code == RADIUS_ATTR_USER_NAME) {
  195. wpa_hexdump_ascii(MSG_DEBUG, "EAP-TTLS: User-Name",
  196. dpos, dlen);
  197. parse->user_name = dpos;
  198. parse->user_name_len = dlen;
  199. } else if (vendor_id == 0 &&
  200. avp_code == RADIUS_ATTR_USER_PASSWORD) {
  201. u8 *password = dpos;
  202. size_t password_len = dlen;
  203. while (password_len > 0 &&
  204. password[password_len - 1] == '\0') {
  205. password_len--;
  206. }
  207. wpa_hexdump_ascii_key(MSG_DEBUG, "EAP-TTLS: "
  208. "User-Password (PAP)",
  209. password, password_len);
  210. parse->user_password = password;
  211. parse->user_password_len = password_len;
  212. } else if (vendor_id == 0 &&
  213. avp_code == RADIUS_ATTR_CHAP_CHALLENGE) {
  214. wpa_hexdump(MSG_DEBUG,
  215. "EAP-TTLS: CHAP-Challenge (CHAP)",
  216. dpos, dlen);
  217. parse->chap_challenge = dpos;
  218. parse->chap_challenge_len = dlen;
  219. } else if (vendor_id == 0 &&
  220. avp_code == RADIUS_ATTR_CHAP_PASSWORD) {
  221. wpa_hexdump(MSG_DEBUG,
  222. "EAP-TTLS: CHAP-Password (CHAP)",
  223. dpos, dlen);
  224. parse->chap_password = dpos;
  225. parse->chap_password_len = dlen;
  226. } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
  227. avp_code == RADIUS_ATTR_MS_CHAP_CHALLENGE) {
  228. wpa_hexdump(MSG_DEBUG,
  229. "EAP-TTLS: MS-CHAP-Challenge",
  230. dpos, dlen);
  231. parse->mschap_challenge = dpos;
  232. parse->mschap_challenge_len = dlen;
  233. } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
  234. avp_code == RADIUS_ATTR_MS_CHAP_RESPONSE) {
  235. wpa_hexdump(MSG_DEBUG,
  236. "EAP-TTLS: MS-CHAP-Response (MSCHAP)",
  237. dpos, dlen);
  238. parse->mschap_response = dpos;
  239. parse->mschap_response_len = dlen;
  240. } else if (vendor_id == RADIUS_VENDOR_ID_MICROSOFT &&
  241. avp_code == RADIUS_ATTR_MS_CHAP2_RESPONSE) {
  242. wpa_hexdump(MSG_DEBUG,
  243. "EAP-TTLS: MS-CHAP2-Response (MSCHAPV2)",
  244. dpos, dlen);
  245. parse->mschap2_response = dpos;
  246. parse->mschap2_response_len = dlen;
  247. } else if (avp_flags & AVP_FLAGS_MANDATORY) {
  248. wpa_printf(MSG_WARNING, "EAP-TTLS: Unsupported "
  249. "mandatory AVP code %d vendor_id %d - "
  250. "dropped", (int) avp_code, (int) vendor_id);
  251. goto fail;
  252. } else {
  253. wpa_printf(MSG_DEBUG, "EAP-TTLS: Ignoring unsupported "
  254. "AVP code %d vendor_id %d",
  255. (int) avp_code, (int) vendor_id);
  256. }
  257. pad = (4 - (avp_length & 3)) & 3;
  258. pos += avp_length + pad;
  259. left -= avp_length + pad;
  260. }
  261. return 0;
  262. fail:
  263. os_free(parse->eap);
  264. parse->eap = NULL;
  265. return -1;
  266. }
  267. static u8 * eap_ttls_implicit_challenge(struct eap_sm *sm,
  268. struct eap_ttls_data *data, size_t len)
  269. {
  270. return eap_server_tls_derive_key(sm, &data->ssl, "ttls challenge",
  271. len);
  272. }
  273. static void * eap_ttls_init(struct eap_sm *sm)
  274. {
  275. struct eap_ttls_data *data;
  276. data = os_zalloc(sizeof(*data));
  277. if (data == NULL)
  278. return NULL;
  279. data->ttls_version = EAP_TTLS_VERSION;
  280. data->state = START;
  281. if (eap_server_tls_ssl_init(sm, &data->ssl, 0)) {
  282. wpa_printf(MSG_INFO, "EAP-TTLS: Failed to initialize SSL.");
  283. eap_ttls_reset(sm, data);
  284. return NULL;
  285. }
  286. return data;
  287. }
  288. static void eap_ttls_reset(struct eap_sm *sm, void *priv)
  289. {
  290. struct eap_ttls_data *data = priv;
  291. if (data == NULL)
  292. return;
  293. if (data->phase2_priv && data->phase2_method)
  294. data->phase2_method->reset(sm, data->phase2_priv);
  295. eap_server_tls_ssl_deinit(sm, &data->ssl);
  296. wpabuf_free(data->pending_phase2_eap_resp);
  297. os_free(data);
  298. }
  299. static struct wpabuf * eap_ttls_build_start(struct eap_sm *sm,
  300. struct eap_ttls_data *data, u8 id)
  301. {
  302. struct wpabuf *req;
  303. req = eap_msg_alloc(EAP_VENDOR_IETF, EAP_TYPE_TTLS, 1,
  304. EAP_CODE_REQUEST, id);
  305. if (req == NULL) {
  306. wpa_printf(MSG_ERROR, "EAP-TTLS: Failed to allocate memory for"
  307. " request");
  308. eap_ttls_state(data, FAILURE);
  309. return NULL;
  310. }
  311. wpabuf_put_u8(req, EAP_TLS_FLAGS_START | data->ttls_version);
  312. eap_ttls_state(data, PHASE1);
  313. return req;
  314. }
  315. static struct wpabuf * eap_ttls_build_phase2_eap_req(
  316. struct eap_sm *sm, struct eap_ttls_data *data, u8 id)
  317. {
  318. struct wpabuf *buf, *encr_req;
  319. buf = data->phase2_method->buildReq(sm, data->phase2_priv, id);
  320. if (buf == NULL)
  321. return NULL;
  322. wpa_hexdump_buf_key(MSG_DEBUG,
  323. "EAP-TTLS/EAP: Encapsulate Phase 2 data", buf);
  324. buf = eap_ttls_avp_encapsulate(buf, RADIUS_ATTR_EAP_MESSAGE, 1);
  325. if (buf == NULL) {
  326. wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Failed to encapsulate "
  327. "packet");
  328. return NULL;
  329. }
  330. wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TTLS/EAP: Encrypt encapsulated "
  331. "Phase 2 data", buf);
  332. encr_req = eap_server_tls_encrypt(sm, &data->ssl, buf);
  333. wpabuf_free(buf);
  334. return encr_req;
  335. }
  336. static struct wpabuf * eap_ttls_build_phase2_mschapv2(
  337. struct eap_sm *sm, struct eap_ttls_data *data)
  338. {
  339. struct wpabuf *encr_req, msgbuf;
  340. u8 *req, *pos, *end;
  341. int ret;
  342. pos = req = os_malloc(100);
  343. if (req == NULL)
  344. return NULL;
  345. end = req + 100;
  346. if (data->mschapv2_resp_ok) {
  347. pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP2_SUCCESS,
  348. RADIUS_VENDOR_ID_MICROSOFT, 1, 43);
  349. *pos++ = data->mschapv2_ident;
  350. ret = os_snprintf((char *) pos, end - pos, "S=");
  351. if (ret >= 0 && ret < end - pos)
  352. pos += ret;
  353. pos += wpa_snprintf_hex_uppercase(
  354. (char *) pos, end - pos, data->mschapv2_auth_response,
  355. sizeof(data->mschapv2_auth_response));
  356. } else {
  357. pos = eap_ttls_avp_hdr(pos, RADIUS_ATTR_MS_CHAP_ERROR,
  358. RADIUS_VENDOR_ID_MICROSOFT, 1, 6);
  359. os_memcpy(pos, "Failed", 6);
  360. pos += 6;
  361. AVP_PAD(req, pos);
  362. }
  363. wpabuf_set(&msgbuf, req, pos - req);
  364. wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Encrypting Phase 2 "
  365. "data", &msgbuf);
  366. encr_req = eap_server_tls_encrypt(sm, &data->ssl, &msgbuf);
  367. os_free(req);
  368. return encr_req;
  369. }
  370. static struct wpabuf * eap_ttls_buildReq(struct eap_sm *sm, void *priv, u8 id)
  371. {
  372. struct eap_ttls_data *data = priv;
  373. if (data->ssl.state == FRAG_ACK) {
  374. return eap_server_tls_build_ack(id, EAP_TYPE_TTLS,
  375. data->ttls_version);
  376. }
  377. if (data->ssl.state == WAIT_FRAG_ACK) {
  378. return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_TTLS,
  379. data->ttls_version, id);
  380. }
  381. switch (data->state) {
  382. case START:
  383. return eap_ttls_build_start(sm, data, id);
  384. case PHASE1:
  385. if (tls_connection_established(sm->ssl_ctx, data->ssl.conn)) {
  386. wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase1 done, "
  387. "starting Phase2");
  388. eap_ttls_state(data, PHASE2_START);
  389. }
  390. break;
  391. case PHASE2_METHOD:
  392. wpabuf_free(data->ssl.tls_out);
  393. data->ssl.tls_out_pos = 0;
  394. data->ssl.tls_out = eap_ttls_build_phase2_eap_req(sm, data,
  395. id);
  396. break;
  397. case PHASE2_MSCHAPV2_RESP:
  398. wpabuf_free(data->ssl.tls_out);
  399. data->ssl.tls_out_pos = 0;
  400. data->ssl.tls_out = eap_ttls_build_phase2_mschapv2(sm, data);
  401. break;
  402. default:
  403. wpa_printf(MSG_DEBUG, "EAP-TTLS: %s - unexpected state %d",
  404. __func__, data->state);
  405. return NULL;
  406. }
  407. return eap_server_tls_build_msg(&data->ssl, EAP_TYPE_TTLS,
  408. data->ttls_version, id);
  409. }
  410. static Boolean eap_ttls_check(struct eap_sm *sm, void *priv,
  411. struct wpabuf *respData)
  412. {
  413. const u8 *pos;
  414. size_t len;
  415. pos = eap_hdr_validate(EAP_VENDOR_IETF, EAP_TYPE_TTLS, respData, &len);
  416. if (pos == NULL || len < 1) {
  417. wpa_printf(MSG_INFO, "EAP-TTLS: Invalid frame");
  418. return TRUE;
  419. }
  420. return FALSE;
  421. }
  422. static void eap_ttls_process_phase2_pap(struct eap_sm *sm,
  423. struct eap_ttls_data *data,
  424. const u8 *user_password,
  425. size_t user_password_len)
  426. {
  427. if (!sm->user || !sm->user->password || sm->user->password_hash ||
  428. !(sm->user->ttls_auth & EAP_TTLS_AUTH_PAP)) {
  429. wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: No plaintext user "
  430. "password configured");
  431. eap_ttls_state(data, FAILURE);
  432. return;
  433. }
  434. if (sm->user->password_len != user_password_len ||
  435. os_memcmp_const(sm->user->password, user_password,
  436. user_password_len) != 0) {
  437. wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: Invalid user password");
  438. eap_ttls_state(data, FAILURE);
  439. return;
  440. }
  441. wpa_printf(MSG_DEBUG, "EAP-TTLS/PAP: Correct user password");
  442. eap_ttls_state(data, SUCCESS);
  443. }
  444. static void eap_ttls_process_phase2_chap(struct eap_sm *sm,
  445. struct eap_ttls_data *data,
  446. const u8 *challenge,
  447. size_t challenge_len,
  448. const u8 *password,
  449. size_t password_len)
  450. {
  451. u8 *chal, hash[CHAP_MD5_LEN];
  452. if (challenge == NULL || password == NULL ||
  453. challenge_len != EAP_TTLS_CHAP_CHALLENGE_LEN ||
  454. password_len != 1 + EAP_TTLS_CHAP_PASSWORD_LEN) {
  455. wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Invalid CHAP attributes "
  456. "(challenge len %lu password len %lu)",
  457. (unsigned long) challenge_len,
  458. (unsigned long) password_len);
  459. eap_ttls_state(data, FAILURE);
  460. return;
  461. }
  462. if (!sm->user || !sm->user->password || sm->user->password_hash ||
  463. !(sm->user->ttls_auth & EAP_TTLS_AUTH_CHAP)) {
  464. wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: No plaintext user "
  465. "password configured");
  466. eap_ttls_state(data, FAILURE);
  467. return;
  468. }
  469. chal = eap_ttls_implicit_challenge(sm, data,
  470. EAP_TTLS_CHAP_CHALLENGE_LEN + 1);
  471. if (chal == NULL) {
  472. wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Failed to generate "
  473. "challenge from TLS data");
  474. eap_ttls_state(data, FAILURE);
  475. return;
  476. }
  477. if (os_memcmp_const(challenge, chal, EAP_TTLS_CHAP_CHALLENGE_LEN)
  478. != 0 ||
  479. password[0] != chal[EAP_TTLS_CHAP_CHALLENGE_LEN]) {
  480. wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Challenge mismatch");
  481. os_free(chal);
  482. eap_ttls_state(data, FAILURE);
  483. return;
  484. }
  485. os_free(chal);
  486. /* MD5(Ident + Password + Challenge) */
  487. chap_md5(password[0], sm->user->password, sm->user->password_len,
  488. challenge, challenge_len, hash);
  489. if (os_memcmp_const(hash, password + 1, EAP_TTLS_CHAP_PASSWORD_LEN) ==
  490. 0) {
  491. wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Correct user password");
  492. eap_ttls_state(data, SUCCESS);
  493. } else {
  494. wpa_printf(MSG_DEBUG, "EAP-TTLS/CHAP: Invalid user password");
  495. eap_ttls_state(data, FAILURE);
  496. }
  497. }
  498. static void eap_ttls_process_phase2_mschap(struct eap_sm *sm,
  499. struct eap_ttls_data *data,
  500. u8 *challenge, size_t challenge_len,
  501. u8 *response, size_t response_len)
  502. {
  503. u8 *chal, nt_response[24];
  504. if (challenge == NULL || response == NULL ||
  505. challenge_len != EAP_TTLS_MSCHAP_CHALLENGE_LEN ||
  506. response_len != EAP_TTLS_MSCHAP_RESPONSE_LEN) {
  507. wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Invalid MS-CHAP "
  508. "attributes (challenge len %lu response len %lu)",
  509. (unsigned long) challenge_len,
  510. (unsigned long) response_len);
  511. eap_ttls_state(data, FAILURE);
  512. return;
  513. }
  514. if (!sm->user || !sm->user->password ||
  515. !(sm->user->ttls_auth & EAP_TTLS_AUTH_MSCHAP)) {
  516. wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: No user password "
  517. "configured");
  518. eap_ttls_state(data, FAILURE);
  519. return;
  520. }
  521. chal = eap_ttls_implicit_challenge(sm, data,
  522. EAP_TTLS_MSCHAP_CHALLENGE_LEN + 1);
  523. if (chal == NULL) {
  524. wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Failed to generate "
  525. "challenge from TLS data");
  526. eap_ttls_state(data, FAILURE);
  527. return;
  528. }
  529. if (os_memcmp_const(challenge, chal, EAP_TTLS_MSCHAP_CHALLENGE_LEN)
  530. != 0 ||
  531. response[0] != chal[EAP_TTLS_MSCHAP_CHALLENGE_LEN]) {
  532. wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Challenge mismatch");
  533. os_free(chal);
  534. eap_ttls_state(data, FAILURE);
  535. return;
  536. }
  537. os_free(chal);
  538. if (sm->user->password_hash)
  539. challenge_response(challenge, sm->user->password, nt_response);
  540. else
  541. nt_challenge_response(challenge, sm->user->password,
  542. sm->user->password_len, nt_response);
  543. if (os_memcmp_const(nt_response, response + 2 + 24, 24) == 0) {
  544. wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Correct response");
  545. eap_ttls_state(data, SUCCESS);
  546. } else {
  547. wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAP: Invalid NT-Response");
  548. wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAP: Received",
  549. response + 2 + 24, 24);
  550. wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAP: Expected",
  551. nt_response, 24);
  552. eap_ttls_state(data, FAILURE);
  553. }
  554. }
  555. static void eap_ttls_process_phase2_mschapv2(struct eap_sm *sm,
  556. struct eap_ttls_data *data,
  557. u8 *challenge,
  558. size_t challenge_len,
  559. u8 *response, size_t response_len)
  560. {
  561. u8 *chal, *username, nt_response[24], *rx_resp, *peer_challenge,
  562. *auth_challenge;
  563. size_t username_len, i;
  564. if (challenge == NULL || response == NULL ||
  565. challenge_len != EAP_TTLS_MSCHAPV2_CHALLENGE_LEN ||
  566. response_len != EAP_TTLS_MSCHAPV2_RESPONSE_LEN) {
  567. wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Invalid MS-CHAP2 "
  568. "attributes (challenge len %lu response len %lu)",
  569. (unsigned long) challenge_len,
  570. (unsigned long) response_len);
  571. eap_ttls_state(data, FAILURE);
  572. return;
  573. }
  574. if (!sm->user || !sm->user->password ||
  575. !(sm->user->ttls_auth & EAP_TTLS_AUTH_MSCHAPV2)) {
  576. wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: No user password "
  577. "configured");
  578. eap_ttls_state(data, FAILURE);
  579. return;
  580. }
  581. if (sm->identity == NULL) {
  582. wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: No user identity "
  583. "known");
  584. eap_ttls_state(data, FAILURE);
  585. return;
  586. }
  587. /* MSCHAPv2 does not include optional domain name in the
  588. * challenge-response calculation, so remove domain prefix
  589. * (if present). */
  590. username = sm->identity;
  591. username_len = sm->identity_len;
  592. for (i = 0; i < username_len; i++) {
  593. if (username[i] == '\\') {
  594. username_len -= i + 1;
  595. username += i + 1;
  596. break;
  597. }
  598. }
  599. chal = eap_ttls_implicit_challenge(
  600. sm, data, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 1);
  601. if (chal == NULL) {
  602. wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Failed to generate "
  603. "challenge from TLS data");
  604. eap_ttls_state(data, FAILURE);
  605. return;
  606. }
  607. if (os_memcmp_const(challenge, chal, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN)
  608. != 0 ||
  609. response[0] != chal[EAP_TTLS_MSCHAPV2_CHALLENGE_LEN]) {
  610. wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Challenge mismatch");
  611. os_free(chal);
  612. eap_ttls_state(data, FAILURE);
  613. return;
  614. }
  615. os_free(chal);
  616. auth_challenge = challenge;
  617. peer_challenge = response + 2;
  618. wpa_hexdump_ascii(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: User",
  619. username, username_len);
  620. wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: auth_challenge",
  621. auth_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);
  622. wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: peer_challenge",
  623. peer_challenge, EAP_TTLS_MSCHAPV2_CHALLENGE_LEN);
  624. if (sm->user->password_hash) {
  625. generate_nt_response_pwhash(auth_challenge, peer_challenge,
  626. username, username_len,
  627. sm->user->password,
  628. nt_response);
  629. } else {
  630. generate_nt_response(auth_challenge, peer_challenge,
  631. username, username_len,
  632. sm->user->password,
  633. sm->user->password_len,
  634. nt_response);
  635. }
  636. rx_resp = response + 2 + EAP_TTLS_MSCHAPV2_CHALLENGE_LEN + 8;
  637. if (os_memcmp_const(nt_response, rx_resp, 24) == 0) {
  638. wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Correct "
  639. "NT-Response");
  640. data->mschapv2_resp_ok = 1;
  641. if (sm->user->password_hash) {
  642. generate_authenticator_response_pwhash(
  643. sm->user->password,
  644. peer_challenge, auth_challenge,
  645. username, username_len, nt_response,
  646. data->mschapv2_auth_response);
  647. } else {
  648. generate_authenticator_response(
  649. sm->user->password, sm->user->password_len,
  650. peer_challenge, auth_challenge,
  651. username, username_len, nt_response,
  652. data->mschapv2_auth_response);
  653. }
  654. } else {
  655. wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Invalid "
  656. "NT-Response");
  657. wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: Received",
  658. rx_resp, 24);
  659. wpa_hexdump(MSG_MSGDUMP, "EAP-TTLS/MSCHAPV2: Expected",
  660. nt_response, 24);
  661. data->mschapv2_resp_ok = 0;
  662. }
  663. eap_ttls_state(data, PHASE2_MSCHAPV2_RESP);
  664. data->mschapv2_ident = response[0];
  665. }
  666. static int eap_ttls_phase2_eap_init(struct eap_sm *sm,
  667. struct eap_ttls_data *data,
  668. EapType eap_type)
  669. {
  670. if (data->phase2_priv && data->phase2_method) {
  671. data->phase2_method->reset(sm, data->phase2_priv);
  672. data->phase2_method = NULL;
  673. data->phase2_priv = NULL;
  674. }
  675. data->phase2_method = eap_server_get_eap_method(EAP_VENDOR_IETF,
  676. eap_type);
  677. if (!data->phase2_method)
  678. return -1;
  679. sm->init_phase2 = 1;
  680. data->phase2_priv = data->phase2_method->init(sm);
  681. sm->init_phase2 = 0;
  682. return data->phase2_priv == NULL ? -1 : 0;
  683. }
  684. static void eap_ttls_process_phase2_eap_response(struct eap_sm *sm,
  685. struct eap_ttls_data *data,
  686. u8 *in_data, size_t in_len)
  687. {
  688. u8 next_type = EAP_TYPE_NONE;
  689. struct eap_hdr *hdr;
  690. u8 *pos;
  691. size_t left;
  692. struct wpabuf buf;
  693. const struct eap_method *m = data->phase2_method;
  694. void *priv = data->phase2_priv;
  695. if (priv == NULL) {
  696. wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: %s - Phase2 not "
  697. "initialized?!", __func__);
  698. return;
  699. }
  700. hdr = (struct eap_hdr *) in_data;
  701. pos = (u8 *) (hdr + 1);
  702. if (in_len > sizeof(*hdr) && *pos == EAP_TYPE_NAK) {
  703. left = in_len - sizeof(*hdr);
  704. wpa_hexdump(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 type Nak'ed; "
  705. "allowed types", pos + 1, left - 1);
  706. eap_sm_process_nak(sm, pos + 1, left - 1);
  707. if (sm->user && sm->user_eap_method_index < EAP_MAX_METHODS &&
  708. sm->user->methods[sm->user_eap_method_index].method !=
  709. EAP_TYPE_NONE) {
  710. next_type = sm->user->methods[
  711. sm->user_eap_method_index++].method;
  712. wpa_printf(MSG_DEBUG, "EAP-TTLS: try EAP type %d",
  713. next_type);
  714. if (eap_ttls_phase2_eap_init(sm, data, next_type)) {
  715. wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to "
  716. "initialize EAP type %d",
  717. next_type);
  718. eap_ttls_state(data, FAILURE);
  719. return;
  720. }
  721. } else {
  722. eap_ttls_state(data, FAILURE);
  723. }
  724. return;
  725. }
  726. wpabuf_set(&buf, in_data, in_len);
  727. if (m->check(sm, priv, &buf)) {
  728. wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 check() asked to "
  729. "ignore the packet");
  730. return;
  731. }
  732. m->process(sm, priv, &buf);
  733. if (sm->method_pending == METHOD_PENDING_WAIT) {
  734. wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 method is in "
  735. "pending wait state - save decrypted response");
  736. wpabuf_free(data->pending_phase2_eap_resp);
  737. data->pending_phase2_eap_resp = wpabuf_dup(&buf);
  738. }
  739. if (!m->isDone(sm, priv))
  740. return;
  741. if (!m->isSuccess(sm, priv)) {
  742. wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: Phase2 method failed");
  743. eap_ttls_state(data, FAILURE);
  744. return;
  745. }
  746. switch (data->state) {
  747. case PHASE2_START:
  748. if (eap_user_get(sm, sm->identity, sm->identity_len, 1) != 0) {
  749. wpa_hexdump_ascii(MSG_DEBUG, "EAP_TTLS: Phase2 "
  750. "Identity not found in the user "
  751. "database",
  752. sm->identity, sm->identity_len);
  753. eap_ttls_state(data, FAILURE);
  754. break;
  755. }
  756. eap_ttls_state(data, PHASE2_METHOD);
  757. next_type = sm->user->methods[0].method;
  758. sm->user_eap_method_index = 1;
  759. wpa_printf(MSG_DEBUG, "EAP-TTLS: try EAP type %d", next_type);
  760. if (eap_ttls_phase2_eap_init(sm, data, next_type)) {
  761. wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to initialize "
  762. "EAP type %d", next_type);
  763. eap_ttls_state(data, FAILURE);
  764. }
  765. break;
  766. case PHASE2_METHOD:
  767. eap_ttls_state(data, SUCCESS);
  768. break;
  769. case FAILURE:
  770. break;
  771. default:
  772. wpa_printf(MSG_DEBUG, "EAP-TTLS: %s - unexpected state %d",
  773. __func__, data->state);
  774. break;
  775. }
  776. }
  777. static void eap_ttls_process_phase2_eap(struct eap_sm *sm,
  778. struct eap_ttls_data *data,
  779. const u8 *eap, size_t eap_len)
  780. {
  781. struct eap_hdr *hdr;
  782. size_t len;
  783. if (data->state == PHASE2_START) {
  784. wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: initializing Phase 2");
  785. if (eap_ttls_phase2_eap_init(sm, data, EAP_TYPE_IDENTITY) < 0)
  786. {
  787. wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: failed to "
  788. "initialize EAP-Identity");
  789. return;
  790. }
  791. }
  792. if (eap_len < sizeof(*hdr)) {
  793. wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: too short Phase 2 EAP "
  794. "packet (len=%lu)", (unsigned long) eap_len);
  795. return;
  796. }
  797. hdr = (struct eap_hdr *) eap;
  798. len = be_to_host16(hdr->length);
  799. wpa_printf(MSG_DEBUG, "EAP-TTLS/EAP: received Phase 2 EAP: code=%d "
  800. "identifier=%d length=%lu", hdr->code, hdr->identifier,
  801. (unsigned long) len);
  802. if (len > eap_len) {
  803. wpa_printf(MSG_INFO, "EAP-TTLS/EAP: Length mismatch in Phase 2"
  804. " EAP frame (hdr len=%lu, data len in AVP=%lu)",
  805. (unsigned long) len, (unsigned long) eap_len);
  806. return;
  807. }
  808. switch (hdr->code) {
  809. case EAP_CODE_RESPONSE:
  810. eap_ttls_process_phase2_eap_response(sm, data, (u8 *) hdr,
  811. len);
  812. break;
  813. default:
  814. wpa_printf(MSG_INFO, "EAP-TTLS/EAP: Unexpected code=%d in "
  815. "Phase 2 EAP header", hdr->code);
  816. break;
  817. }
  818. }
  819. static void eap_ttls_process_phase2(struct eap_sm *sm,
  820. struct eap_ttls_data *data,
  821. struct wpabuf *in_buf)
  822. {
  823. struct wpabuf *in_decrypted;
  824. struct eap_ttls_avp parse;
  825. wpa_printf(MSG_DEBUG, "EAP-TTLS: received %lu bytes encrypted data for"
  826. " Phase 2", (unsigned long) wpabuf_len(in_buf));
  827. if (data->pending_phase2_eap_resp) {
  828. wpa_printf(MSG_DEBUG, "EAP-TTLS: Pending Phase 2 EAP response "
  829. "- skip decryption and use old data");
  830. eap_ttls_process_phase2_eap(
  831. sm, data, wpabuf_head(data->pending_phase2_eap_resp),
  832. wpabuf_len(data->pending_phase2_eap_resp));
  833. wpabuf_free(data->pending_phase2_eap_resp);
  834. data->pending_phase2_eap_resp = NULL;
  835. return;
  836. }
  837. in_decrypted = tls_connection_decrypt(sm->ssl_ctx, data->ssl.conn,
  838. in_buf);
  839. if (in_decrypted == NULL) {
  840. wpa_printf(MSG_INFO, "EAP-TTLS: Failed to decrypt Phase 2 "
  841. "data");
  842. eap_ttls_state(data, FAILURE);
  843. return;
  844. }
  845. wpa_hexdump_buf_key(MSG_DEBUG, "EAP-TTLS: Decrypted Phase 2 EAP",
  846. in_decrypted);
  847. if (eap_ttls_avp_parse(in_decrypted, &parse) < 0) {
  848. wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to parse AVPs");
  849. wpabuf_free(in_decrypted);
  850. eap_ttls_state(data, FAILURE);
  851. return;
  852. }
  853. if (parse.user_name) {
  854. char *nbuf;
  855. nbuf = os_malloc(parse.user_name_len * 4 + 1);
  856. if (nbuf) {
  857. printf_encode(nbuf, parse.user_name_len * 4 + 1,
  858. parse.user_name,
  859. parse.user_name_len);
  860. eap_log_msg(sm, "TTLS-User-Name '%s'", nbuf);
  861. os_free(nbuf);
  862. }
  863. os_free(sm->identity);
  864. sm->identity = os_malloc(parse.user_name_len);
  865. if (sm->identity == NULL) {
  866. eap_ttls_state(data, FAILURE);
  867. goto done;
  868. }
  869. os_memcpy(sm->identity, parse.user_name, parse.user_name_len);
  870. sm->identity_len = parse.user_name_len;
  871. if (eap_user_get(sm, parse.user_name, parse.user_name_len, 1)
  872. != 0) {
  873. wpa_printf(MSG_DEBUG, "EAP-TTLS: Phase2 Identity not "
  874. "found in the user database");
  875. eap_ttls_state(data, FAILURE);
  876. goto done;
  877. }
  878. }
  879. #ifdef EAP_SERVER_TNC
  880. if (data->tnc_started && parse.eap == NULL) {
  881. wpa_printf(MSG_DEBUG, "EAP-TTLS: TNC started but no EAP "
  882. "response from peer");
  883. eap_ttls_state(data, FAILURE);
  884. goto done;
  885. }
  886. #endif /* EAP_SERVER_TNC */
  887. if (parse.eap) {
  888. eap_ttls_process_phase2_eap(sm, data, parse.eap,
  889. parse.eap_len);
  890. } else if (parse.user_password) {
  891. eap_ttls_process_phase2_pap(sm, data, parse.user_password,
  892. parse.user_password_len);
  893. } else if (parse.chap_password) {
  894. eap_ttls_process_phase2_chap(sm, data,
  895. parse.chap_challenge,
  896. parse.chap_challenge_len,
  897. parse.chap_password,
  898. parse.chap_password_len);
  899. } else if (parse.mschap_response) {
  900. eap_ttls_process_phase2_mschap(sm, data,
  901. parse.mschap_challenge,
  902. parse.mschap_challenge_len,
  903. parse.mschap_response,
  904. parse.mschap_response_len);
  905. } else if (parse.mschap2_response) {
  906. eap_ttls_process_phase2_mschapv2(sm, data,
  907. parse.mschap_challenge,
  908. parse.mschap_challenge_len,
  909. parse.mschap2_response,
  910. parse.mschap2_response_len);
  911. }
  912. done:
  913. wpabuf_free(in_decrypted);
  914. os_free(parse.eap);
  915. }
  916. static void eap_ttls_start_tnc(struct eap_sm *sm, struct eap_ttls_data *data)
  917. {
  918. #ifdef EAP_SERVER_TNC
  919. if (!sm->tnc || data->state != SUCCESS || data->tnc_started)
  920. return;
  921. wpa_printf(MSG_DEBUG, "EAP-TTLS: Initialize TNC");
  922. if (eap_ttls_phase2_eap_init(sm, data, EAP_TYPE_TNC)) {
  923. wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to initialize TNC");
  924. eap_ttls_state(data, FAILURE);
  925. return;
  926. }
  927. data->tnc_started = 1;
  928. eap_ttls_state(data, PHASE2_METHOD);
  929. #endif /* EAP_SERVER_TNC */
  930. }
  931. static int eap_ttls_process_version(struct eap_sm *sm, void *priv,
  932. int peer_version)
  933. {
  934. struct eap_ttls_data *data = priv;
  935. if (peer_version < data->ttls_version) {
  936. wpa_printf(MSG_DEBUG, "EAP-TTLS: peer ver=%d, own ver=%d; "
  937. "use version %d",
  938. peer_version, data->ttls_version, peer_version);
  939. data->ttls_version = peer_version;
  940. }
  941. return 0;
  942. }
  943. static void eap_ttls_process_msg(struct eap_sm *sm, void *priv,
  944. const struct wpabuf *respData)
  945. {
  946. struct eap_ttls_data *data = priv;
  947. switch (data->state) {
  948. case PHASE1:
  949. if (eap_server_tls_phase1(sm, &data->ssl) < 0)
  950. eap_ttls_state(data, FAILURE);
  951. break;
  952. case PHASE2_START:
  953. case PHASE2_METHOD:
  954. eap_ttls_process_phase2(sm, data, data->ssl.tls_in);
  955. eap_ttls_start_tnc(sm, data);
  956. break;
  957. case PHASE2_MSCHAPV2_RESP:
  958. if (data->mschapv2_resp_ok && wpabuf_len(data->ssl.tls_in) ==
  959. 0) {
  960. wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Peer "
  961. "acknowledged response");
  962. eap_ttls_state(data, SUCCESS);
  963. } else if (!data->mschapv2_resp_ok) {
  964. wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Peer "
  965. "acknowledged error");
  966. eap_ttls_state(data, FAILURE);
  967. } else {
  968. wpa_printf(MSG_DEBUG, "EAP-TTLS/MSCHAPV2: Unexpected "
  969. "frame from peer (payload len %lu, "
  970. "expected empty frame)",
  971. (unsigned long)
  972. wpabuf_len(data->ssl.tls_in));
  973. eap_ttls_state(data, FAILURE);
  974. }
  975. eap_ttls_start_tnc(sm, data);
  976. break;
  977. default:
  978. wpa_printf(MSG_DEBUG, "EAP-TTLS: Unexpected state %d in %s",
  979. data->state, __func__);
  980. break;
  981. }
  982. }
  983. static void eap_ttls_process(struct eap_sm *sm, void *priv,
  984. struct wpabuf *respData)
  985. {
  986. struct eap_ttls_data *data = priv;
  987. if (eap_server_tls_process(sm, &data->ssl, respData, data,
  988. EAP_TYPE_TTLS, eap_ttls_process_version,
  989. eap_ttls_process_msg) < 0)
  990. eap_ttls_state(data, FAILURE);
  991. }
  992. static Boolean eap_ttls_isDone(struct eap_sm *sm, void *priv)
  993. {
  994. struct eap_ttls_data *data = priv;
  995. return data->state == SUCCESS || data->state == FAILURE;
  996. }
  997. static u8 * eap_ttls_getKey(struct eap_sm *sm, void *priv, size_t *len)
  998. {
  999. struct eap_ttls_data *data = priv;
  1000. u8 *eapKeyData;
  1001. if (data->state != SUCCESS)
  1002. return NULL;
  1003. eapKeyData = eap_server_tls_derive_key(sm, &data->ssl,
  1004. "ttls keying material",
  1005. EAP_TLS_KEY_LEN);
  1006. if (eapKeyData) {
  1007. *len = EAP_TLS_KEY_LEN;
  1008. wpa_hexdump_key(MSG_DEBUG, "EAP-TTLS: Derived key",
  1009. eapKeyData, EAP_TLS_KEY_LEN);
  1010. } else {
  1011. wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive key");
  1012. }
  1013. return eapKeyData;
  1014. }
  1015. static Boolean eap_ttls_isSuccess(struct eap_sm *sm, void *priv)
  1016. {
  1017. struct eap_ttls_data *data = priv;
  1018. return data->state == SUCCESS;
  1019. }
  1020. int eap_server_ttls_register(void)
  1021. {
  1022. struct eap_method *eap;
  1023. int ret;
  1024. eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
  1025. EAP_VENDOR_IETF, EAP_TYPE_TTLS, "TTLS");
  1026. if (eap == NULL)
  1027. return -1;
  1028. eap->init = eap_ttls_init;
  1029. eap->reset = eap_ttls_reset;
  1030. eap->buildReq = eap_ttls_buildReq;
  1031. eap->check = eap_ttls_check;
  1032. eap->process = eap_ttls_process;
  1033. eap->isDone = eap_ttls_isDone;
  1034. eap->getKey = eap_ttls_getKey;
  1035. eap->isSuccess = eap_ttls_isSuccess;
  1036. ret = eap_server_method_register(eap);
  1037. if (ret)
  1038. eap_server_method_free(eap);
  1039. return ret;
  1040. }