eap_server_ttls.c 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253
  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. bin_clear_free(data, sizeof(*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 (!os_snprintf_error(end - pos, ret))
  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. static u8 * eap_ttls_get_session_id(struct eap_sm *sm, void *priv, size_t *len)
  1021. {
  1022. struct eap_ttls_data *data = priv;
  1023. if (data->state != SUCCESS)
  1024. return NULL;
  1025. return eap_server_tls_derive_session_id(sm, &data->ssl, EAP_TYPE_TTLS,
  1026. len);
  1027. }
  1028. static u8 * eap_ttls_get_emsk(struct eap_sm *sm, void *priv, size_t *len)
  1029. {
  1030. struct eap_ttls_data *data = priv;
  1031. u8 *eapKeyData, *emsk;
  1032. if (data->state != SUCCESS)
  1033. return NULL;
  1034. eapKeyData = eap_server_tls_derive_key(sm, &data->ssl,
  1035. "ttls keying material",
  1036. EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
  1037. if (eapKeyData) {
  1038. emsk = os_malloc(EAP_EMSK_LEN);
  1039. if (emsk)
  1040. os_memcpy(emsk, eapKeyData + EAP_TLS_KEY_LEN,
  1041. EAP_EMSK_LEN);
  1042. bin_clear_free(eapKeyData, EAP_TLS_KEY_LEN + EAP_EMSK_LEN);
  1043. } else
  1044. emsk = NULL;
  1045. if (emsk) {
  1046. *len = EAP_EMSK_LEN;
  1047. wpa_hexdump(MSG_DEBUG, "EAP-TTLS: Derived EMSK",
  1048. emsk, EAP_EMSK_LEN);
  1049. } else {
  1050. wpa_printf(MSG_DEBUG, "EAP-TTLS: Failed to derive EMSK");
  1051. }
  1052. return emsk;
  1053. }
  1054. int eap_server_ttls_register(void)
  1055. {
  1056. struct eap_method *eap;
  1057. int ret;
  1058. eap = eap_server_method_alloc(EAP_SERVER_METHOD_INTERFACE_VERSION,
  1059. EAP_VENDOR_IETF, EAP_TYPE_TTLS, "TTLS");
  1060. if (eap == NULL)
  1061. return -1;
  1062. eap->init = eap_ttls_init;
  1063. eap->reset = eap_ttls_reset;
  1064. eap->buildReq = eap_ttls_buildReq;
  1065. eap->check = eap_ttls_check;
  1066. eap->process = eap_ttls_process;
  1067. eap->isDone = eap_ttls_isDone;
  1068. eap->getKey = eap_ttls_getKey;
  1069. eap->isSuccess = eap_ttls_isSuccess;
  1070. eap->getSessionId = eap_ttls_get_session_id;
  1071. eap->get_emsk = eap_ttls_get_emsk;
  1072. ret = eap_server_method_register(eap);
  1073. if (ret)
  1074. eap_server_method_free(eap);
  1075. return ret;
  1076. }