|
1 /* |
|
2 * Copyright (c) 2001-2006 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the License "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: EAP and WLAN authentication protocols. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 // This is enumeration of EAPOL source code. |
|
20 #if defined(USE_EAP_MINIMUM_RELEASE_TRACES) |
|
21 #undef EAP_FILE_NUMBER_ENUM |
|
22 #define EAP_FILE_NUMBER_ENUM 95 |
|
23 #undef EAP_FILE_NUMBER_DATE |
|
24 #define EAP_FILE_NUMBER_DATE 1127594498 |
|
25 #endif //#if defined(USE_EAP_MINIMUM_RELEASE_TRACES) |
|
26 |
|
27 |
|
28 // INCLUDE FILES |
|
29 |
|
30 #include "eap_am_memory.h" |
|
31 #include "eap_state_notification.h" |
|
32 #include "eap_type_mschapv2_header.h" |
|
33 #include "eap_type_mschapv2.h" |
|
34 #include "eap_type_mschapv2_credential_store.h" |
|
35 #include "eap_buffer.h" |
|
36 #include "eap_config.h" |
|
37 #include "eap_master_session_key.h" |
|
38 #include "eap_automatic_variable.h" |
|
39 |
|
40 /** |
|
41 * Constructor initializes all member attributes. |
|
42 */ |
|
43 |
|
44 EAP_FUNC_EXPORT eap_type_mschapv2_c::eap_type_mschapv2_c( |
|
45 abs_eap_am_tools_c * const tools, |
|
46 abs_eap_base_type_c * const partner, |
|
47 eap_am_type_mschapv2_c * const am_type_mschapv2, |
|
48 const bool free_am_type_mschapv2, |
|
49 const bool is_client_when_true, |
|
50 const eap_am_network_id_c * const receive_network_id) |
|
51 : eap_base_type_c(tools, partner) |
|
52 , m_am_type_mschapv2(am_type_mschapv2) |
|
53 , m_am_tools(tools) |
|
54 , m_session(tools, is_client_when_true) |
|
55 , m_send_network_id(tools) |
|
56 , m_rand(tools) |
|
57 , m_username_utf8(tools) |
|
58 , m_password_utf8(tools) |
|
59 , m_old_password_utf8(tools) |
|
60 , m_password_hash(tools) |
|
61 , m_password_hash_hash(tools) |
|
62 #if defined(USE_FAST_EAP_TYPE) |
|
63 , m_client_EAP_FAST_challenge(tools) |
|
64 , m_server_EAP_FAST_challenge(tools) |
|
65 #endif //#if defined(USE_FAST_EAP_TYPE) |
|
66 , m_offset(0) |
|
67 , m_mtu_length(0) |
|
68 , m_trailer_length(0) |
|
69 , m_error_code(0) |
|
70 , m_is_valid(false) |
|
71 , m_is_client(is_client_when_true) |
|
72 , m_free_am_type_mschapv2(free_am_type_mschapv2) |
|
73 , m_is_pending(false) |
|
74 , m_identity_asked(false) |
|
75 , m_wait_eap_success(false) |
|
76 , m_wait_eap_success_packet(true) |
|
77 , m_is_reauthentication(false) |
|
78 , m_is_notification_sent(false) |
|
79 , m_shutdown_was_called(false) |
|
80 , m_password_prompt_enabled(true) |
|
81 , m_identifier(0) |
|
82 , m_mschapv2id(0) |
|
83 #if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) |
|
84 , m_use_implicit_challenge(false) |
|
85 #endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) |
|
86 #if defined(EAP_MSCHAPV2_SERVER) |
|
87 , m_do_password_expiration_tests(false) |
|
88 , m_password_expired(false) |
|
89 #endif //#if defined(EAP_MSCHAPV2_SERVER) |
|
90 , m_do_wrong_password_tests(false) |
|
91 , m_use_eap_expanded_type(false) |
|
92 #if defined(USE_FAST_EAP_TYPE) |
|
93 , m_use_EAP_FAST_full_key(false) |
|
94 , m_use_EAP_FAST_challenge(false) |
|
95 #endif //#if defined(USE_FAST_EAP_TYPE) |
|
96 { |
|
97 EAP_TRACE_DEBUG( |
|
98 m_am_tools, |
|
99 TRACE_FLAGS_DEFAULT, |
|
100 (EAPL("eap_type_mschapv2_c::eap_type_mschapv2_c(): this = 0x%08x, ") |
|
101 EAPL("partner 0x%08x, type partner 0x%08x, compiled %s %s\n"), |
|
102 this, |
|
103 partner, |
|
104 get_type_partner(), |
|
105 __DATE__, |
|
106 __TIME__)); |
|
107 |
|
108 m_am_type_mschapv2->set_am_partner(this); |
|
109 |
|
110 { |
|
111 // Here we swap the addresses. |
|
112 eap_am_network_id_c send_network_id(m_am_tools, |
|
113 receive_network_id->get_destination_id(), |
|
114 receive_network_id->get_source_id(), |
|
115 receive_network_id->get_type()); |
|
116 |
|
117 eap_status_e status = m_send_network_id.set_copy_of_network_id(&send_network_id); |
|
118 |
|
119 if (status != eap_status_ok |
|
120 || m_send_network_id.get_is_valid_data() == false) |
|
121 { |
|
122 (void)EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
123 return; |
|
124 } |
|
125 } |
|
126 |
|
127 m_is_valid = true; |
|
128 } |
|
129 |
|
130 //-------------------------------------------------- |
|
131 |
|
132 EAP_FUNC_EXPORT eap_type_mschapv2_c::~eap_type_mschapv2_c() |
|
133 { |
|
134 EAP_TRACE_DEBUG( |
|
135 m_am_tools, |
|
136 TRACE_FLAGS_DEFAULT, |
|
137 (EAPL("eap_type_mschapv2_c::~eap_type_mschapv2_c(): this = 0x%08x\n"), |
|
138 this)); |
|
139 |
|
140 EAP_ASSERT(m_shutdown_was_called == true); |
|
141 |
|
142 if (m_free_am_type_mschapv2 == true) |
|
143 { |
|
144 delete m_am_type_mschapv2; |
|
145 } |
|
146 m_free_am_type_mschapv2 = false; |
|
147 } |
|
148 |
|
149 //-------------------------------------------------- |
|
150 |
|
151 EAP_FUNC_EXPORT eap_status_e eap_type_mschapv2_c::shutdown() |
|
152 { |
|
153 EAP_TRACE_DEBUG( |
|
154 m_am_tools, |
|
155 TRACE_FLAGS_DEFAULT, |
|
156 (EAPL("eap_type_mschapv2_c::shutdown(): this = 0x%08x, m_session.get_state()=%d, m_is_notification_sent=%d\n"), |
|
157 this, |
|
158 m_session.get_state(), |
|
159 m_is_notification_sent)); |
|
160 |
|
161 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_type_mschapv2_c::shutdown()"); |
|
162 |
|
163 m_am_type_mschapv2->shutdown(); |
|
164 m_shutdown_was_called = true; |
|
165 |
|
166 if (m_session.get_state() != eap_type_mschapv2_state_none) |
|
167 { |
|
168 if (m_is_notification_sent == false) |
|
169 { |
|
170 finish_unsuccessful_authentication(false); |
|
171 } |
|
172 } |
|
173 |
|
174 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
175 } |
|
176 |
|
177 //-------------------------------------------------- |
|
178 |
|
179 EAP_FUNC_EXPORT void eap_type_mschapv2_c::set_is_valid() |
|
180 { |
|
181 m_is_valid = true; |
|
182 } |
|
183 |
|
184 //-------------------------------------------------- |
|
185 |
|
186 EAP_FUNC_EXPORT bool eap_type_mschapv2_c::get_is_valid() |
|
187 { |
|
188 return m_is_valid; |
|
189 } |
|
190 |
|
191 //-------------------------------------------------- |
|
192 |
|
193 EAP_FUNC_EXPORT bool eap_type_mschapv2_c::get_is_client() |
|
194 { |
|
195 return m_is_client; |
|
196 } |
|
197 |
|
198 //-------------------------------------------------- |
|
199 |
|
200 void eap_type_mschapv2_c::send_error_notification(const eap_status_e error) |
|
201 { |
|
202 // Notifies the lower level of an authentication error. |
|
203 eap_state_notification_c notification( |
|
204 m_am_tools, |
|
205 &m_send_network_id, |
|
206 m_is_client, |
|
207 eap_state_notification_eap, |
|
208 eap_protocol_layer_general, |
|
209 eap_type_mschapv2, |
|
210 eap_state_none, |
|
211 eap_general_state_authentication_error, |
|
212 0, |
|
213 false); |
|
214 |
|
215 notification.set_authentication_error(error); |
|
216 |
|
217 get_type_partner()->state_notification(¬ification); |
|
218 } |
|
219 |
|
220 //-------------------------------------------------- |
|
221 |
|
222 eap_buf_chain_wr_c * eap_type_mschapv2_c::create_send_packet(u32_t length) |
|
223 { |
|
224 eap_buf_chain_wr_c * packet = new eap_buf_chain_wr_c( |
|
225 eap_write_buffer, |
|
226 m_am_tools, |
|
227 length + m_offset + m_trailer_length); |
|
228 if (!packet) |
|
229 { |
|
230 return 0; |
|
231 } |
|
232 if (packet->get_is_valid() == false) |
|
233 { |
|
234 delete packet; |
|
235 return 0; |
|
236 } |
|
237 packet->set_data_length(length + m_offset); |
|
238 |
|
239 return packet; |
|
240 } |
|
241 |
|
242 //-------------------------------------------------- |
|
243 |
|
244 eap_status_e eap_type_mschapv2_c::packet_send( |
|
245 eap_buf_chain_wr_c * const data, |
|
246 const u32_t data_length) |
|
247 { |
|
248 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
249 if (m_mtu_length < data_length) |
|
250 { |
|
251 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); |
|
252 } |
|
253 |
|
254 if (data->get_is_valid_data() == false) |
|
255 { |
|
256 EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n"))); |
|
257 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
258 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
259 } |
|
260 |
|
261 eap_status_e status = get_type_partner()->packet_send( |
|
262 &m_send_network_id, |
|
263 data, |
|
264 m_offset, |
|
265 data_length, |
|
266 data->get_buffer_length()); |
|
267 |
|
268 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
269 return EAP_STATUS_RETURN(m_am_tools, status); |
|
270 } |
|
271 |
|
272 //-------------------------------------------------- |
|
273 |
|
274 EAP_FUNC_EXPORT eap_status_e eap_type_mschapv2_c::finish_successful_authentication() |
|
275 { |
|
276 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
277 EAP_TRACE_DEBUG( |
|
278 m_am_tools, |
|
279 TRACE_FLAGS_DEFAULT, |
|
280 (EAPL("EAP_type_MSCHAPV2: %s: EAP-SUCCESS: function: eap_type_mschapv2_c::finish_successful_authentication()\n"), |
|
281 (m_is_client == true) ? "client": "server")); |
|
282 |
|
283 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_type_mschapv2_c::finish_successful_authentication()"); |
|
284 |
|
285 eap_state_notification_c notification( |
|
286 m_am_tools, |
|
287 &m_send_network_id, |
|
288 m_is_client, |
|
289 eap_state_notification_eap, |
|
290 eap_protocol_layer_eap, |
|
291 eap_type_mschapv2, |
|
292 eap_state_none, |
|
293 eap_state_authentication_finished_successfully, |
|
294 m_identifier, |
|
295 true); |
|
296 get_type_partner()->state_notification(¬ification); |
|
297 |
|
298 // set notification flag |
|
299 m_is_notification_sent = true; |
|
300 |
|
301 // Store credential for reauthentication (client only) |
|
302 //if (m_is_client) |
|
303 { |
|
304 eap_variable_data_c key(m_am_tools); |
|
305 eap_status_e status = m_am_type_mschapv2->get_memory_store_key(&key); |
|
306 if (status != eap_status_ok) |
|
307 { |
|
308 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
309 return EAP_STATUS_RETURN(m_am_tools, status); |
|
310 } |
|
311 |
|
312 status = key.add_data( |
|
313 &m_is_client, |
|
314 sizeof(m_is_client)); |
|
315 if (status != eap_status_ok) |
|
316 { |
|
317 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
318 return EAP_STATUS_RETURN(m_am_tools, status); |
|
319 } |
|
320 |
|
321 // Remove the old data. Do not care status. |
|
322 (void) m_am_tools->memory_store_remove_data(&key); |
|
323 |
|
324 EAP_TRACE_DEBUG( |
|
325 m_am_tools, |
|
326 TRACE_FLAGS_DEFAULT, |
|
327 (EAPL("%s: EAP_type_MSCHAPV2: finish_successful_authentication(): Credentials removed from mem store\n"), |
|
328 (m_is_client == true) ? "client": "server")); |
|
329 |
|
330 // Store the creditials always, if the password prompt is NOT enabled or |
|
331 // if the Session is valid. |
|
332 |
|
333 if(m_password_prompt_enabled == false |
|
334 || m_am_type_mschapv2->is_session_valid() == true) |
|
335 { |
|
336 EAP_TRACE_DEBUG( |
|
337 m_am_tools, |
|
338 TRACE_FLAGS_DEFAULT, |
|
339 (EAPL("%s: EAP_type_MSCHAPV2: finish_successful_authentication(): Session valid or PW prompt disabled, Storing Credentials\n"), |
|
340 (m_is_client == true) ? "client": "server")); |
|
341 |
|
342 eap_tlv_message_data_c tlv_data(m_am_tools); |
|
343 |
|
344 status = tlv_data.add_message_data( |
|
345 eap_type_mschapv2_stored_username, |
|
346 m_username_utf8.get_data_length(), |
|
347 m_username_utf8.get_data()); |
|
348 if (status != eap_status_ok) |
|
349 { |
|
350 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
351 return EAP_STATUS_RETURN(m_am_tools, status); |
|
352 } |
|
353 |
|
354 status = tlv_data.add_message_data( |
|
355 eap_type_mschapv2_stored_password, |
|
356 m_password_utf8.get_data_length(), |
|
357 m_password_utf8.get_data()); |
|
358 if (status != eap_status_ok) |
|
359 { |
|
360 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
361 return EAP_STATUS_RETURN(m_am_tools, status); |
|
362 } |
|
363 |
|
364 #if defined(EAP_MSCHAPV2_SERVER) |
|
365 status = tlv_data.add_message_data( |
|
366 eap_type_mschapv2_stored_password_expired_flag, |
|
367 sizeof(m_password_expired), |
|
368 &m_password_expired); |
|
369 if (status != eap_status_ok) |
|
370 { |
|
371 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
372 return EAP_STATUS_RETURN(m_am_tools, status); |
|
373 } |
|
374 #endif //#if defined(EAP_MSCHAPV2_SERVER) |
|
375 |
|
376 status = m_am_tools->memory_store_add_data( |
|
377 &key, |
|
378 &tlv_data, |
|
379 eap_type_default_credential_timeout); |
|
380 if (status != eap_status_ok) |
|
381 { |
|
382 EAP_TRACE_DEBUG( |
|
383 m_am_tools, |
|
384 TRACE_FLAGS_DEFAULT, |
|
385 (EAPL("EAP_type_MSCHAPV2: finish_successful_authentication(): cannot store credentials\n"))); |
|
386 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
387 return EAP_STATUS_RETURN(m_am_tools, status); |
|
388 } |
|
389 |
|
390 EAP_TRACE_DEBUG( |
|
391 m_am_tools, |
|
392 TRACE_FLAGS_DEFAULT, |
|
393 (EAPL("%s: EAP_type_MSCHAPV2: finish_successful_authentication(): Credentials stored \n"), |
|
394 (m_is_client == true) ? "client": "server")); |
|
395 |
|
396 } // End of if(m_password_prompt_enabled == true .... |
|
397 |
|
398 } |
|
399 |
|
400 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
401 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
402 } |
|
403 |
|
404 //-------------------------------------------------- |
|
405 |
|
406 EAP_FUNC_EXPORT eap_status_e eap_type_mschapv2_c::finish_unsuccessful_authentication( |
|
407 const bool authentication_cancelled) |
|
408 { |
|
409 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
410 EAP_TRACE_DEBUG( |
|
411 m_am_tools, |
|
412 TRACE_FLAGS_DEFAULT, |
|
413 (EAPL("ERROR: %s: EAP_type_MSCHAPV2: FAILED: function: eap_type_mschapv2_c::finish_unsuccessful_authentication()\n"), |
|
414 (m_is_client == true) ? "client": "server")); |
|
415 |
|
416 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_type_mschapv2_c::finish_unsuccessful_authentication()"); |
|
417 |
|
418 if (m_is_client == true) |
|
419 { |
|
420 if (authentication_cancelled == true) |
|
421 { |
|
422 eap_state_notification_c notification( |
|
423 m_am_tools, |
|
424 &m_send_network_id, |
|
425 m_is_client, |
|
426 eap_state_notification_eap, |
|
427 eap_protocol_layer_general, // This must be used with eap_general_state_authentication_cancelled. |
|
428 eap_type_mschapv2, |
|
429 eap_state_none, |
|
430 eap_general_state_authentication_cancelled, |
|
431 m_identifier, |
|
432 false); |
|
433 |
|
434 notification.set_authentication_error(eap_status_authentication_failure); |
|
435 |
|
436 get_type_partner()->state_notification(¬ification); |
|
437 } |
|
438 else |
|
439 { |
|
440 eap_state_notification_c notification( |
|
441 m_am_tools, |
|
442 &m_send_network_id, |
|
443 m_is_client, |
|
444 eap_state_notification_eap, |
|
445 eap_protocol_layer_eap, |
|
446 eap_type_mschapv2, |
|
447 eap_state_none, |
|
448 eap_state_authentication_terminated_unsuccessfully, |
|
449 m_identifier, |
|
450 false); |
|
451 |
|
452 notification.set_authentication_error(eap_status_authentication_failure); |
|
453 |
|
454 get_type_partner()->state_notification(¬ification); |
|
455 } |
|
456 |
|
457 #if defined(USE_USER_NOTIFICATIONS) |
|
458 eap_variable_data_c string(m_am_tools); |
|
459 eap_status_e status = m_am_type_mschapv2->read_auth_failure_string(EAP_MSCHAPV2_ERROR_AUTHENTICATION_FAILURE, string); |
|
460 if (status == eap_status_ok) |
|
461 { |
|
462 eap_state_notification_c notification( |
|
463 m_am_tools, |
|
464 &m_send_network_id, |
|
465 m_is_client, |
|
466 eap_state_notification_eap, |
|
467 eap_protocol_layer_general, // This must be used with eap_general_state_show_notification_string. |
|
468 eap_type_mschapv2, |
|
469 eap_state_none, |
|
470 eap_general_state_show_notification_string, |
|
471 0, |
|
472 false); |
|
473 status = notification.set_notification_string(&string, true); |
|
474 if (status == eap_status_ok) |
|
475 { |
|
476 get_type_partner()->state_notification(¬ification); |
|
477 } |
|
478 } |
|
479 #endif //#if defined(USE_USER_NOTIFICATIONS) |
|
480 } |
|
481 else |
|
482 { |
|
483 eap_state_notification_c notification( |
|
484 m_am_tools, |
|
485 &m_send_network_id, |
|
486 m_is_client, |
|
487 eap_state_notification_eap, |
|
488 eap_protocol_layer_eap, |
|
489 eap_type_mschapv2, |
|
490 eap_state_none, |
|
491 eap_state_authentication_terminated_unsuccessfully, |
|
492 m_identifier, |
|
493 false); |
|
494 |
|
495 notification.set_authentication_error(eap_status_authentication_failure); |
|
496 |
|
497 get_type_partner()->state_notification(¬ification); |
|
498 } |
|
499 |
|
500 EAP_TRACE_DEBUG( |
|
501 m_am_tools, |
|
502 TRACE_FLAGS_DEFAULT, |
|
503 (EAPL("%s: EAP_type_MSCHAPV2: finish_unsuccessful_authentication(): EAP-FAILED\n"), |
|
504 (m_is_client == true) ? "client": "server")); |
|
505 |
|
506 // set notification flag |
|
507 m_is_notification_sent = true; |
|
508 |
|
509 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
510 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
511 } |
|
512 |
|
513 //-------------------------------------------------- |
|
514 |
|
515 EAP_FUNC_EXPORT eap_status_e eap_type_mschapv2_c::packet_process( |
|
516 const eap_am_network_id_c * const /*receive_network_id*/, |
|
517 eap_header_wr_c * const received_eap, |
|
518 const u32_t eap_packet_length) |
|
519 { |
|
520 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
521 eap_status_e status = eap_status_drop_packet_quietly; |
|
522 |
|
523 if (eap_packet_length > received_eap->get_header_buffer_length()) |
|
524 { |
|
525 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
526 return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); |
|
527 } |
|
528 |
|
529 if (eap_packet_length < eap_header_base_c::get_header_length()) // Without type code |
|
530 { |
|
531 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
532 return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); |
|
533 } |
|
534 |
|
535 if (received_eap->get_type() == eap_type_notification) |
|
536 { |
|
537 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
538 return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); |
|
539 } |
|
540 |
|
541 #ifdef EAP_MSCHAPV2_SERVER |
|
542 if (m_is_client) // Client |
|
543 { |
|
544 #endif |
|
545 |
|
546 status = client_packet_process( |
|
547 received_eap, |
|
548 eap_packet_length); |
|
549 |
|
550 #ifdef EAP_MSCHAPV2_SERVER |
|
551 } |
|
552 else // Server |
|
553 { |
|
554 status = server_packet_process( |
|
555 received_eap, |
|
556 eap_packet_length); |
|
557 } |
|
558 #endif |
|
559 |
|
560 if (status == eap_status_ok) |
|
561 { |
|
562 EAP_GENERAL_HEADER_SET_ERROR_DETECTED(received_eap, false); |
|
563 } |
|
564 |
|
565 if (status == eap_status_ok |
|
566 || status == eap_status_pending_request |
|
567 || status == eap_status_drop_packet_quietly) |
|
568 { |
|
569 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
570 return EAP_STATUS_RETURN(m_am_tools, status); |
|
571 } |
|
572 |
|
573 // Internal error |
|
574 status = finish_unsuccessful_authentication(false); |
|
575 |
|
576 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
577 return EAP_STATUS_RETURN(m_am_tools, status); |
|
578 } |
|
579 |
|
580 //-------------------------------------------------- |
|
581 |
|
582 EAP_FUNC_EXPORT eap_status_e eap_type_mschapv2_c::configure() |
|
583 { |
|
584 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
585 |
|
586 EAP_TRACE_DEBUG( |
|
587 m_am_tools, |
|
588 TRACE_FLAGS_DEFAULT, |
|
589 (EAPL("eap_type_mschapv2_c::configure(): this = 0x%08x\n"), |
|
590 this)); |
|
591 |
|
592 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_type_mschapv2_c::configure()"); |
|
593 |
|
594 eap_status_e status = eap_status_process_general_error; |
|
595 |
|
596 status = m_am_type_mschapv2->configure(); |
|
597 if (status != eap_status_ok) |
|
598 { |
|
599 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
600 return EAP_STATUS_RETURN(m_am_tools, status); |
|
601 } |
|
602 |
|
603 m_offset = get_type_partner()->get_header_offset(&m_mtu_length, &m_trailer_length); |
|
604 |
|
605 // read configures |
|
606 |
|
607 // Password promt |
|
608 eap_variable_data_c password_prompt(m_am_tools); |
|
609 |
|
610 status = m_am_type_mschapv2->type_configure_read( |
|
611 cf_str_EAP_MSCHAPV2_password_prompt.get_field(), |
|
612 &password_prompt); |
|
613 if (status == eap_status_ok) |
|
614 { |
|
615 const u32_t * const flag = reinterpret_cast<u32_t *>( |
|
616 password_prompt.get_data(sizeof(u32_t))); |
|
617 if (flag && *flag == 0) |
|
618 { |
|
619 m_password_prompt_enabled = false; |
|
620 } |
|
621 else |
|
622 { |
|
623 m_password_prompt_enabled = true; |
|
624 } |
|
625 } |
|
626 |
|
627 // Username |
|
628 eap_variable_data_c username_uc(m_am_tools); |
|
629 |
|
630 status = m_am_type_mschapv2->type_configure_read( |
|
631 cf_str_EAP_MSCHAPV2_username.get_field(), |
|
632 &m_username_utf8); |
|
633 if (status != eap_status_ok |
|
634 || m_username_utf8.get_is_valid() == false) |
|
635 { |
|
636 // This is optional. |
|
637 } |
|
638 |
|
639 // Password |
|
640 status = m_am_type_mschapv2->type_configure_read( |
|
641 cf_str_EAP_MSCHAPV2_password.get_field(), |
|
642 &m_password_utf8); |
|
643 if (status != eap_status_ok |
|
644 || m_password_utf8.get_is_valid() == false) |
|
645 { |
|
646 // This is optional. |
|
647 } |
|
648 |
|
649 if (m_is_client == true |
|
650 && m_password_prompt_enabled == true) |
|
651 { |
|
652 m_password_utf8.reset(); |
|
653 } |
|
654 |
|
655 |
|
656 |
|
657 #if defined(EAP_MSCHAPV2_SERVER) |
|
658 { |
|
659 eap_variable_data_c do_password_expiration_tests(m_am_tools); |
|
660 |
|
661 status = m_am_type_mschapv2->type_configure_read( |
|
662 cf_str_EAP_MSCHAPV2_do_password_expiration_tests.get_field(), |
|
663 &do_password_expiration_tests); |
|
664 if (status == eap_status_ok) |
|
665 { |
|
666 const u32_t * const flag = reinterpret_cast<u32_t *>( |
|
667 do_password_expiration_tests.get_data(sizeof(u32_t))); |
|
668 if (flag != 0 |
|
669 && *flag == 0) |
|
670 { |
|
671 m_do_password_expiration_tests = false; |
|
672 } |
|
673 else |
|
674 { |
|
675 m_do_password_expiration_tests = true; |
|
676 } |
|
677 } |
|
678 } |
|
679 #endif //#if defined(EAP_MSCHAPV2_SERVER) |
|
680 |
|
681 |
|
682 if (m_is_client == true) |
|
683 { |
|
684 eap_variable_data_c do_wrong_password_tests(m_am_tools); |
|
685 |
|
686 status = m_am_type_mschapv2->type_configure_read( |
|
687 cf_str_EAP_MSCHAPV2_do_wrong_password_tests.get_field(), |
|
688 &do_wrong_password_tests); |
|
689 if (status == eap_status_ok) |
|
690 { |
|
691 const u32_t * const flag = reinterpret_cast<u32_t *>( |
|
692 do_wrong_password_tests.get_data(sizeof(u32_t))); |
|
693 if (flag != 0 |
|
694 && *flag == 0) |
|
695 { |
|
696 m_do_wrong_password_tests = false; |
|
697 } |
|
698 else |
|
699 { |
|
700 m_do_wrong_password_tests = true; |
|
701 } |
|
702 } |
|
703 } |
|
704 |
|
705 #if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) |
|
706 { |
|
707 eap_variable_data_c use_implicit_challenge(m_am_tools); |
|
708 |
|
709 status = m_am_type_mschapv2->type_configure_read( |
|
710 cf_str_EAP_MSCHAPV2_use_implicit_challenge.get_field(), |
|
711 &use_implicit_challenge); |
|
712 if (status == eap_status_ok) |
|
713 { |
|
714 const u32_t * const flag = reinterpret_cast<u32_t *>( |
|
715 use_implicit_challenge.get_data(sizeof(u32_t))); |
|
716 if (flag != 0 && *flag != 0) |
|
717 { |
|
718 m_use_implicit_challenge = true; |
|
719 } |
|
720 else |
|
721 { |
|
722 m_use_implicit_challenge = false; |
|
723 } |
|
724 } |
|
725 } |
|
726 #endif //#if defined(EAP_USE_TTLS_PLAIN_MS_CHAP_V2_HACK) |
|
727 |
|
728 //---------------------------------------------------------- |
|
729 |
|
730 #if defined(USE_EAP_EXPANDED_TYPES) |
|
731 { |
|
732 eap_variable_data_c use_eap_expanded_type(m_am_tools); |
|
733 |
|
734 eap_status_e status = m_am_type_mschapv2->type_configure_read( |
|
735 cf_str_EAP_MSCHAPV2_use_eap_expanded_type.get_field(), |
|
736 &use_eap_expanded_type); |
|
737 |
|
738 if (status != eap_status_ok) |
|
739 { |
|
740 status = m_am_type_mschapv2->type_configure_read( |
|
741 cf_str_EAP_CORE_use_eap_expanded_type.get_field(), |
|
742 &use_eap_expanded_type); |
|
743 } |
|
744 |
|
745 if (status == eap_status_ok |
|
746 && use_eap_expanded_type.get_data_length() == sizeof(u32_t) |
|
747 && use_eap_expanded_type.get_data() != 0) |
|
748 { |
|
749 u32_t *flag = reinterpret_cast<u32_t *>(use_eap_expanded_type.get_data(use_eap_expanded_type.get_data_length())); |
|
750 |
|
751 if (flag != 0) |
|
752 { |
|
753 if ((*flag) != 0ul) |
|
754 { |
|
755 m_use_eap_expanded_type = true; |
|
756 } |
|
757 else |
|
758 { |
|
759 m_use_eap_expanded_type = false; |
|
760 } |
|
761 } |
|
762 } |
|
763 } |
|
764 #endif //#if defined(USE_EAP_EXPANDED_TYPES) |
|
765 |
|
766 //---------------------------------------------------------- |
|
767 |
|
768 #if defined(USE_FAST_EAP_TYPE) |
|
769 |
|
770 { |
|
771 eap_variable_data_c use_EAP_FAST_challenge(m_am_tools); |
|
772 |
|
773 status = m_am_type_mschapv2->type_configure_read( |
|
774 cf_str_EAP_MSCHAPV2_use_EAP_FAST_challenge.get_field(), |
|
775 &use_EAP_FAST_challenge); |
|
776 if (status == eap_status_ok) |
|
777 { |
|
778 const u32_t * const flag = reinterpret_cast<u32_t *>( |
|
779 use_EAP_FAST_challenge.get_data(sizeof(u32_t))); |
|
780 if (flag != 0 && *flag != 0) |
|
781 { |
|
782 m_use_EAP_FAST_challenge = true; |
|
783 } |
|
784 else |
|
785 { |
|
786 m_use_EAP_FAST_challenge = false; |
|
787 } |
|
788 } |
|
789 } |
|
790 |
|
791 if (m_use_EAP_FAST_challenge == true) |
|
792 { |
|
793 status = m_am_type_mschapv2->type_configure_read( |
|
794 cf_str_EAP_MSCHAPV2_client_EAP_FAST_challenge.get_field(), |
|
795 &m_client_EAP_FAST_challenge); |
|
796 if (status != eap_status_ok |
|
797 || m_client_EAP_FAST_challenge.get_is_valid_data() == false) |
|
798 { |
|
799 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
800 return EAP_STATUS_RETURN(m_am_tools, status); |
|
801 } |
|
802 |
|
803 EAP_TRACE_DATA_DEBUG( |
|
804 m_am_tools, |
|
805 TRACE_FLAGS_DEFAULT, |
|
806 (EAPL("eap_type_mschapv2_c::configure(): m_client_EAP_FAST_challenge"), |
|
807 m_client_EAP_FAST_challenge.get_data(), |
|
808 m_client_EAP_FAST_challenge.get_data_length())); |
|
809 |
|
810 status = m_am_type_mschapv2->type_configure_read( |
|
811 cf_str_EAP_MSCHAPV2_server_EAP_FAST_challenge.get_field(), |
|
812 &m_server_EAP_FAST_challenge); |
|
813 if (status != eap_status_ok |
|
814 || m_server_EAP_FAST_challenge.get_is_valid_data() == false) |
|
815 { |
|
816 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
817 return EAP_STATUS_RETURN(m_am_tools, status); |
|
818 } |
|
819 |
|
820 EAP_TRACE_DATA_DEBUG( |
|
821 m_am_tools, |
|
822 TRACE_FLAGS_DEFAULT, |
|
823 (EAPL("eap_type_mschapv2_c::configure(): m_server_EAP_FAST_challenge"), |
|
824 m_server_EAP_FAST_challenge.get_data(), |
|
825 m_server_EAP_FAST_challenge.get_data_length())); |
|
826 } |
|
827 |
|
828 { |
|
829 eap_variable_data_c use_EAP_FAST_full_key(m_am_tools); |
|
830 |
|
831 status = m_am_type_mschapv2->type_configure_read( |
|
832 cf_str_EAP_MSCHAPV2_use_EAP_FAST_full_key.get_field(), |
|
833 &use_EAP_FAST_full_key); |
|
834 if (status == eap_status_ok) |
|
835 { |
|
836 const u32_t * const flag = reinterpret_cast<u32_t *>( |
|
837 use_EAP_FAST_full_key.get_data(sizeof(u32_t))); |
|
838 if (flag != 0 && *flag != 0) |
|
839 { |
|
840 m_use_EAP_FAST_full_key = true; |
|
841 } |
|
842 else |
|
843 { |
|
844 m_use_EAP_FAST_full_key = false; |
|
845 } |
|
846 } |
|
847 } |
|
848 |
|
849 |
|
850 #endif //#if defined(USE_FAST_EAP_TYPE) |
|
851 |
|
852 //---------------------------------------------------------- |
|
853 |
|
854 eap_variable_data_c wait_eap_success_prompt(m_am_tools); |
|
855 |
|
856 m_wait_eap_success = true; |
|
857 |
|
858 // Check if the case is reauthentication (client only) |
|
859 //if (m_is_client) |
|
860 { |
|
861 eap_variable_data_c key(m_am_tools); |
|
862 status = m_am_type_mschapv2->get_memory_store_key(&key); |
|
863 if (status != eap_status_ok) |
|
864 { |
|
865 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
866 return EAP_STATUS_RETURN(m_am_tools, status); |
|
867 } |
|
868 |
|
869 status = key.add_data( |
|
870 &m_is_client, |
|
871 sizeof(m_is_client)); |
|
872 if (status != eap_status_ok) |
|
873 { |
|
874 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
875 return EAP_STATUS_RETURN(m_am_tools, status); |
|
876 } |
|
877 |
|
878 eap_tlv_message_data_c tlv_data(m_am_tools); |
|
879 |
|
880 status = m_am_tools->memory_store_get_data( |
|
881 &key, |
|
882 &tlv_data); |
|
883 if (status != eap_status_ok) |
|
884 { |
|
885 EAP_TRACE_DEBUG( |
|
886 m_am_tools, |
|
887 TRACE_FLAGS_DEFAULT, |
|
888 (EAPL("EAP_type_MSCHAPV2: configure(): cannot get credentials\n"))); |
|
889 } |
|
890 else |
|
891 { |
|
892 EAP_TRACE_DEBUG( |
|
893 m_am_tools, |
|
894 TRACE_FLAGS_DEFAULT, |
|
895 (EAPL("EAP_type_MSCHAPV2: configure: credentials found\n"))); |
|
896 |
|
897 // Parse read data. |
|
898 eap_array_c<eap_tlv_header_c> tlv_blocks(m_am_tools); |
|
899 |
|
900 status = tlv_data.parse_message_data(&tlv_blocks); |
|
901 if (status != eap_status_ok) |
|
902 { |
|
903 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
904 return EAP_STATUS_RETURN(m_am_tools, status); |
|
905 } |
|
906 |
|
907 for (u32_t ind = 0ul; ind < tlv_blocks.get_object_count(); ind++) |
|
908 { |
|
909 eap_tlv_header_c * const tlv = tlv_blocks.get_object(ind); |
|
910 if (tlv != 0) |
|
911 { |
|
912 if (tlv->get_type() == eap_type_mschapv2_stored_username) |
|
913 { |
|
914 if (m_username_utf8.get_is_valid_data() == false) |
|
915 { |
|
916 status = m_username_utf8.set_copy_of_buffer( |
|
917 tlv->get_value(tlv->get_value_length()), |
|
918 tlv->get_value_length()); |
|
919 if (status != eap_status_ok) |
|
920 { |
|
921 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
922 return EAP_STATUS_RETURN(m_am_tools, status); |
|
923 } |
|
924 } |
|
925 } |
|
926 else if (tlv->get_type() == eap_type_mschapv2_stored_password) |
|
927 { |
|
928 if (m_password_prompt_enabled == true |
|
929 || m_password_utf8.get_is_valid_data() == false) |
|
930 { |
|
931 status = m_password_utf8.set_copy_of_buffer( |
|
932 tlv->get_value(tlv->get_value_length()), |
|
933 tlv->get_value_length()); |
|
934 if (status != eap_status_ok) |
|
935 { |
|
936 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
937 return EAP_STATUS_RETURN(m_am_tools, status); |
|
938 } |
|
939 } |
|
940 } |
|
941 #if defined(EAP_MSCHAPV2_SERVER) |
|
942 else if (tlv->get_type() == eap_type_mschapv2_stored_password_expired_flag) |
|
943 { |
|
944 bool * const password_expired = reinterpret_cast<bool *>(tlv->get_value(sizeof(*password_expired))); |
|
945 if (password_expired == 0) |
|
946 { |
|
947 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
948 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
949 } |
|
950 |
|
951 m_password_expired = *password_expired; |
|
952 } |
|
953 #endif //#if defined(EAP_MSCHAPV2_SERVER) |
|
954 else |
|
955 { |
|
956 EAP_TRACE_DEBUG( |
|
957 m_am_tools, |
|
958 TRACE_FLAGS_DEFAULT, |
|
959 (EAPL("EAP_type_MSCHAPV2: unknown credential type %d, length %d\n"), |
|
960 tlv->get_type(), |
|
961 tlv->get_value_length())); |
|
962 } |
|
963 } |
|
964 } |
|
965 |
|
966 status = m_am_tools->memory_store_remove_data(&key); |
|
967 EAP_TRACE_DEBUG( |
|
968 m_am_tools, |
|
969 TRACE_FLAGS_DEFAULT, |
|
970 (EAPL("EAP_type_MSCHAPV2: configure: credentials removed from eapol\n"))); |
|
971 |
|
972 m_is_reauthentication = true; |
|
973 m_identity_asked = true; |
|
974 } |
|
975 } |
|
976 |
|
977 EAP_TRACE_DATA_DEBUG( |
|
978 m_am_tools, |
|
979 TRACE_FLAGS_DEFAULT, |
|
980 (EAPL("EAP_type_MSCHAPV2: configure, username:"), |
|
981 m_username_utf8.get_data(), |
|
982 m_username_utf8.get_buffer_length())); |
|
983 |
|
984 EAP_TRACE_DATA_DEBUG( |
|
985 m_am_tools, |
|
986 TRACE_FLAGS_DEFAULT, |
|
987 (EAPL("EAP_type_MSCHAPV2: configure, password:"), |
|
988 m_password_utf8.get_data(), |
|
989 m_password_utf8.get_buffer_length())); |
|
990 |
|
991 |
|
992 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
993 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
994 } |
|
995 |
|
996 //-------------------------------------------------- |
|
997 |
|
998 // This function is to allow reuse of this object. |
|
999 // The whole object state must be reset. |
|
1000 EAP_FUNC_EXPORT eap_status_e eap_type_mschapv2_c::reset() |
|
1001 { |
|
1002 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1003 |
|
1004 EAP_TRACE_DEBUG( |
|
1005 m_am_tools, |
|
1006 TRACE_FLAGS_DEFAULT, |
|
1007 (EAPL("eap_type_mschapv2_c::reset(): this = 0x%08x\n"), |
|
1008 this)); |
|
1009 |
|
1010 EAP_TRACE_RETURN_STRING(m_am_tools, "returns: eap_type_mschapv2_c::reset()"); |
|
1011 |
|
1012 m_session.set_state(eap_type_mschapv2_state_none); |
|
1013 |
|
1014 m_username_utf8.reset(); |
|
1015 eap_variable_data_c username_uc(m_am_tools); |
|
1016 |
|
1017 eap_status_e status = m_am_type_mschapv2->type_configure_read( |
|
1018 cf_str_EAP_MSCHAPV2_username.get_field(), |
|
1019 &m_username_utf8); |
|
1020 if (status != eap_status_ok |
|
1021 || m_username_utf8.get_is_valid() == false) |
|
1022 { |
|
1023 // This is optional. |
|
1024 } |
|
1025 |
|
1026 status = m_am_type_mschapv2->type_configure_read( |
|
1027 cf_str_EAP_MSCHAPV2_password.get_field(), |
|
1028 &m_password_utf8); |
|
1029 if (status != eap_status_ok |
|
1030 || m_password_utf8.get_is_valid() == false) |
|
1031 { |
|
1032 // This is optional. |
|
1033 } |
|
1034 |
|
1035 if (m_is_client == true |
|
1036 && m_password_prompt_enabled == true) |
|
1037 { |
|
1038 m_password_utf8.reset(); |
|
1039 } |
|
1040 |
|
1041 m_old_password_utf8.reset(); |
|
1042 |
|
1043 m_is_notification_sent = false; |
|
1044 m_is_reauthentication = false; |
|
1045 |
|
1046 status = m_am_type_mschapv2->reset(); |
|
1047 if (status != eap_status_ok) |
|
1048 { |
|
1049 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1050 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1051 } |
|
1052 |
|
1053 #if defined(USE_FAST_EAP_TYPE) |
|
1054 |
|
1055 { |
|
1056 eap_variable_data_c use_EAP_FAST_challenge(m_am_tools); |
|
1057 |
|
1058 status = m_am_type_mschapv2->type_configure_read( |
|
1059 cf_str_EAP_MSCHAPV2_use_EAP_FAST_challenge.get_field(), |
|
1060 &use_EAP_FAST_challenge); |
|
1061 if (status == eap_status_ok) |
|
1062 { |
|
1063 const u32_t * const flag = reinterpret_cast<u32_t *>( |
|
1064 use_EAP_FAST_challenge.get_data(sizeof(u32_t))); |
|
1065 if (flag != 0 && *flag != 0) |
|
1066 { |
|
1067 m_use_EAP_FAST_challenge = true; |
|
1068 } |
|
1069 else |
|
1070 { |
|
1071 m_use_EAP_FAST_challenge = false; |
|
1072 } |
|
1073 } |
|
1074 } |
|
1075 |
|
1076 if (m_use_EAP_FAST_challenge == true) |
|
1077 { |
|
1078 status = m_am_type_mschapv2->type_configure_read( |
|
1079 cf_str_EAP_MSCHAPV2_client_EAP_FAST_challenge.get_field(), |
|
1080 &m_client_EAP_FAST_challenge); |
|
1081 if (status != eap_status_ok |
|
1082 || m_client_EAP_FAST_challenge.get_is_valid_data() == false) |
|
1083 { |
|
1084 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1085 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1086 } |
|
1087 |
|
1088 EAP_TRACE_DATA_DEBUG( |
|
1089 m_am_tools, |
|
1090 TRACE_FLAGS_DEFAULT, |
|
1091 (EAPL("eap_type_mschapv2_c::reset(): m_client_EAP_FAST_challenge"), |
|
1092 m_client_EAP_FAST_challenge.get_data(), |
|
1093 m_client_EAP_FAST_challenge.get_data_length())); |
|
1094 |
|
1095 status = m_am_type_mschapv2->type_configure_read( |
|
1096 cf_str_EAP_MSCHAPV2_server_EAP_FAST_challenge.get_field(), |
|
1097 &m_server_EAP_FAST_challenge); |
|
1098 if (status != eap_status_ok |
|
1099 || m_server_EAP_FAST_challenge.get_is_valid_data() == false) |
|
1100 { |
|
1101 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1102 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1103 } |
|
1104 |
|
1105 EAP_TRACE_DATA_DEBUG( |
|
1106 m_am_tools, |
|
1107 TRACE_FLAGS_DEFAULT, |
|
1108 (EAPL("eap_type_mschapv2_c::reset(): m_server_EAP_FAST_challenge"), |
|
1109 m_server_EAP_FAST_challenge.get_data(), |
|
1110 m_server_EAP_FAST_challenge.get_data_length())); |
|
1111 |
|
1112 } |
|
1113 |
|
1114 { |
|
1115 eap_variable_data_c use_EAP_FAST_full_key(m_am_tools); |
|
1116 |
|
1117 status = m_am_type_mschapv2->type_configure_read( |
|
1118 cf_str_EAP_MSCHAPV2_use_EAP_FAST_full_key.get_field(), |
|
1119 &use_EAP_FAST_full_key); |
|
1120 if (status == eap_status_ok) |
|
1121 { |
|
1122 const u32_t * const flag = reinterpret_cast<u32_t *>( |
|
1123 use_EAP_FAST_full_key.get_data(sizeof(u32_t))); |
|
1124 if (flag != 0 && *flag != 0) |
|
1125 { |
|
1126 m_use_EAP_FAST_full_key = true; |
|
1127 } |
|
1128 else |
|
1129 { |
|
1130 m_use_EAP_FAST_full_key = false; |
|
1131 } |
|
1132 } |
|
1133 } |
|
1134 |
|
1135 |
|
1136 #endif //#if defined(USE_FAST_EAP_TYPE) |
|
1137 |
|
1138 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1139 |
|
1140 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
1141 } |
|
1142 |
|
1143 //-------------------------------------------------- |
|
1144 |
|
1145 eap_status_e eap_type_mschapv2_c::mschapv2_convert_unicode_to_ascii( |
|
1146 eap_variable_data_c & dest, |
|
1147 const eap_variable_data_c & src) |
|
1148 { |
|
1149 EAP_TRACE_DEBUG( |
|
1150 m_am_tools, |
|
1151 TRACE_FLAGS_DEFAULT, |
|
1152 (EAPL("eap_type_mschapv2_c::mschapv2_convert_unicode_to_ascii(): this = 0x%08x\n"), |
|
1153 this)); |
|
1154 |
|
1155 if (src.get_is_valid()) |
|
1156 { |
|
1157 u32_t len = src.get_data_length(); |
|
1158 u8_t * ascii = new u8_t[len / 2]; |
|
1159 if (!ascii) |
|
1160 { |
|
1161 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1162 } |
|
1163 u8_t * src_ptr = src.get_data(len); |
|
1164 u32_t dest_len = len / 2; |
|
1165 u32_t i; |
|
1166 for (i = 0; i < dest_len; i++) |
|
1167 { |
|
1168 ascii[i] = src_ptr[i * 2]; |
|
1169 } |
|
1170 |
|
1171 return dest.set_buffer(ascii, dest_len, true, true); |
|
1172 } |
|
1173 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); |
|
1174 } |
|
1175 |
|
1176 //-------------------------------------------------- |
|
1177 |
|
1178 /* Pseudocode implementation can be found from */ |
|
1179 /* RFC 2759 Microsoft PPP CHAP Extensions, Version 2 */ |
|
1180 |
|
1181 //-------------------------------------------------- |
|
1182 |
|
1183 eap_status_e eap_type_mschapv2_c::generate_nt_response( |
|
1184 const u8_t * const authenticator_challenge, |
|
1185 const u8_t * const peer_challenge, |
|
1186 const u8_t * const username_utf8, |
|
1187 const u32_t username_size, |
|
1188 const eap_variable_data_c * const password_hash, |
|
1189 u8_t * const response) |
|
1190 { |
|
1191 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1192 |
|
1193 EAP_TRACE_DEBUG( |
|
1194 m_am_tools, |
|
1195 TRACE_FLAGS_DEFAULT, |
|
1196 (EAPL("eap_type_mschapv2_c::generate_nt_response(): this = 0x%08x\n"), |
|
1197 this)); |
|
1198 |
|
1199 if (!authenticator_challenge |
|
1200 || !peer_challenge |
|
1201 || !username_utf8 |
|
1202 || username_size == 0 |
|
1203 || username_size > EAP_MSCHAPV2_USERNAME_MAX_SIZE |
|
1204 || !password_hash |
|
1205 || !response) |
|
1206 { |
|
1207 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); |
|
1208 } |
|
1209 |
|
1210 EAP_TRACE_DATA_DEBUG( |
|
1211 m_am_tools, |
|
1212 TRACE_FLAGS_DEFAULT, |
|
1213 (EAPL("EAP_type_MSCHAPV2: generate_nt_response, authenticator challenge:"), |
|
1214 authenticator_challenge, |
|
1215 EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE)); |
|
1216 |
|
1217 EAP_TRACE_DATA_DEBUG( |
|
1218 m_am_tools, |
|
1219 TRACE_FLAGS_DEFAULT, |
|
1220 (EAPL("EAP_type_MSCHAPV2: generate_nt_response, peer challenge:"), |
|
1221 peer_challenge, |
|
1222 EAP_MSCHAPV2_PEER_CHALLENGE_SIZE)); |
|
1223 |
|
1224 EAP_TRACE_DATA_DEBUG( |
|
1225 m_am_tools, |
|
1226 TRACE_FLAGS_DEFAULT, |
|
1227 (EAPL("EAP_type_MSCHAPV2: generate_nt_response, username_utf8:"), |
|
1228 username_utf8, |
|
1229 username_size)); |
|
1230 |
|
1231 EAP_TRACE_DATA_DEBUG( |
|
1232 m_am_tools, |
|
1233 TRACE_FLAGS_DEFAULT, |
|
1234 (EAPL("EAP_type_MSCHAPV2: generate_nt_response, password_hash:"), |
|
1235 password_hash->get_data(), |
|
1236 password_hash->get_data_length())); |
|
1237 |
|
1238 u8_t * const challenge = new u8_t[8]; |
|
1239 if (!challenge) |
|
1240 { |
|
1241 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1242 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1243 } |
|
1244 |
|
1245 eap_status_e status = challenge_hash( |
|
1246 peer_challenge, |
|
1247 authenticator_challenge, |
|
1248 username_utf8, |
|
1249 username_size, |
|
1250 challenge); |
|
1251 if (status != eap_status_ok) |
|
1252 { |
|
1253 delete [] challenge; |
|
1254 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1255 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1256 } |
|
1257 |
|
1258 EAP_TRACE_DATA_DEBUG( |
|
1259 m_am_tools, |
|
1260 TRACE_FLAGS_DEFAULT, |
|
1261 (EAPL("EAP_type_MSCHAPV2: generate_nt_response, challenge_hash:"), |
|
1262 challenge, |
|
1263 EAP_MSCHAPV2_CHALLENGE_HASH_SIZE)); |
|
1264 |
|
1265 status = challenge_response( |
|
1266 challenge, |
|
1267 password_hash->get_data(), |
|
1268 response); |
|
1269 delete [] challenge; |
|
1270 |
|
1271 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1272 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1273 } |
|
1274 |
|
1275 //-------------------------------------------------- |
|
1276 |
|
1277 eap_status_e eap_type_mschapv2_c::challenge_hash( |
|
1278 const u8_t * const peer_challenge, |
|
1279 const u8_t * const authenticator_challenge, |
|
1280 const u8_t * const username, |
|
1281 const u32_t username_size, |
|
1282 u8_t * const challenge) |
|
1283 { |
|
1284 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1285 |
|
1286 EAP_TRACE_DEBUG( |
|
1287 m_am_tools, |
|
1288 TRACE_FLAGS_DEFAULT, |
|
1289 (EAPL("eap_type_mschapv2_c::challenge_hash(): this = 0x%08x\n"), |
|
1290 this)); |
|
1291 |
|
1292 if (!peer_challenge |
|
1293 || !authenticator_challenge |
|
1294 || !username |
|
1295 || username_size == 0 |
|
1296 || username_size > EAP_MSCHAPV2_USERNAME_MAX_SIZE |
|
1297 || !challenge) |
|
1298 { |
|
1299 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1300 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); |
|
1301 } |
|
1302 |
|
1303 crypto_sha1_c sha1(m_am_tools); |
|
1304 |
|
1305 eap_status_e status = sha1.hash_init(); |
|
1306 if (status != eap_status_ok) |
|
1307 { |
|
1308 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1309 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1310 } |
|
1311 |
|
1312 status = sha1.hash_update(peer_challenge, EAP_MSCHAPV2_MD4_DIGEST_SIZE); |
|
1313 if (status != eap_status_ok) |
|
1314 { |
|
1315 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1316 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1317 } |
|
1318 |
|
1319 status = sha1.hash_update(authenticator_challenge, EAP_MSCHAPV2_AUTHENTICATOR_CHALLENGE_SIZE); |
|
1320 if (status != eap_status_ok) |
|
1321 { |
|
1322 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1323 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1324 } |
|
1325 |
|
1326 // username without domain part |
|
1327 u32_t i; |
|
1328 for (i = username_size; i > 0 && username[i - 1] != '\\'; i--) |
|
1329 { |
|
1330 // Nothing to do, the index is the output. |
|
1331 } |
|
1332 |
|
1333 status = sha1.hash_update(username + i, username_size - i); |
|
1334 if (status != eap_status_ok) |
|
1335 { |
|
1336 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1337 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1338 } |
|
1339 |
|
1340 u8_t * const digest = new u8_t[EAP_MSCHAPV2_SHA1_DIGEST_SIZE]; |
|
1341 if (!digest) |
|
1342 { |
|
1343 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1344 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1345 } |
|
1346 |
|
1347 status = sha1.hash_final(digest, 0); |
|
1348 if (status != eap_status_ok) |
|
1349 { |
|
1350 delete [] digest; |
|
1351 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1352 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1353 } |
|
1354 |
|
1355 m_am_tools->memmove(challenge, digest, EAP_MSCHAPV2_CHALLENGE_HASH_SIZE); |
|
1356 |
|
1357 delete [] digest; |
|
1358 |
|
1359 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1360 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
1361 } |
|
1362 |
|
1363 //-------------------------------------------------- |
|
1364 |
|
1365 eap_status_e eap_type_mschapv2_c::challenge_response( |
|
1366 const u8_t * const challenge, // 8 bytes |
|
1367 const u8_t * const password_hash, // 16 bytes |
|
1368 u8_t * const response) // 24 bytes |
|
1369 { |
|
1370 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1371 |
|
1372 EAP_TRACE_DEBUG( |
|
1373 m_am_tools, |
|
1374 TRACE_FLAGS_DEFAULT, |
|
1375 (EAPL("eap_type_mschapv2_c::challenge_response(): this = 0x%08x\n"), |
|
1376 this)); |
|
1377 |
|
1378 if (!challenge |
|
1379 || !password_hash |
|
1380 || !response) |
|
1381 { |
|
1382 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1383 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); |
|
1384 } |
|
1385 |
|
1386 // 3rd 7-octets of password_hash has to be zero padded |
|
1387 u8_t * zero_padded_password_hash_last_part = new u8_t[7]; |
|
1388 if (!zero_padded_password_hash_last_part) |
|
1389 { |
|
1390 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1391 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1392 } |
|
1393 |
|
1394 m_am_tools->memmove( |
|
1395 zero_padded_password_hash_last_part, |
|
1396 password_hash + 14, // 2 * 7 bytes |
|
1397 2); // 16 - 2 * 7 bytes |
|
1398 |
|
1399 // Zero padding |
|
1400 m_am_tools->memset( |
|
1401 zero_padded_password_hash_last_part + 2, // 16 - 2 * 7 |
|
1402 0, // 7 - 2 |
|
1403 5); |
|
1404 |
|
1405 eap_status_e status = des_encrypt( |
|
1406 challenge, |
|
1407 zero_padded_password_hash_last_part, // 3rd 7-octets of (zero_padded_)password_hash |
|
1408 response + 16); // 3rd 8-octets of response |
|
1409 |
|
1410 delete [] zero_padded_password_hash_last_part; |
|
1411 |
|
1412 if (status != eap_status_ok) |
|
1413 { |
|
1414 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1415 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1416 } |
|
1417 |
|
1418 status = des_encrypt( |
|
1419 challenge, |
|
1420 password_hash, // 1st 7-octets of password_hash |
|
1421 response); // 1st 8-octets of response |
|
1422 |
|
1423 if (status != eap_status_ok) |
|
1424 { |
|
1425 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1426 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1427 } |
|
1428 |
|
1429 status = des_encrypt( |
|
1430 challenge, |
|
1431 password_hash + 7, // 2nd 7-octets of password_hash |
|
1432 response + 8); // 2nd 8-octets of response |
|
1433 |
|
1434 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1435 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1436 } |
|
1437 |
|
1438 //-------------------------------------------------- |
|
1439 |
|
1440 eap_status_e eap_type_mschapv2_c::des_crypt( |
|
1441 const u8_t * const data_in, // 8 octets |
|
1442 const u8_t * const key, // 56 bits |
|
1443 u8_t * const data_out, |
|
1444 const bool is_encrypt) |
|
1445 { |
|
1446 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1447 |
|
1448 EAP_TRACE_DEBUG( |
|
1449 m_am_tools, |
|
1450 TRACE_FLAGS_DEFAULT, |
|
1451 (EAPL("eap_type_mschapv2_c::des_crypt(): this = 0x%08x\n"), |
|
1452 this)); |
|
1453 |
|
1454 if (!data_in |
|
1455 || !key |
|
1456 || !data_out) |
|
1457 { |
|
1458 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1459 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); |
|
1460 } |
|
1461 |
|
1462 u8_t * const newkey = new u8_t[3 * EAP_MSCHAPV2_DES_KEY_SIZE]; // 3des key is triple size |
|
1463 |
|
1464 if (!newkey) |
|
1465 { |
|
1466 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1467 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1468 } |
|
1469 |
|
1470 m_am_tools->memset(newkey, 0, 3 * EAP_MSCHAPV2_DES_KEY_SIZE); // 3 * 8 bytes |
|
1471 |
|
1472 // Add parity bits to key, 56 -> 64 bits |
|
1473 |
|
1474 // First octet |
|
1475 // key bit shifting [1, 7] |
|
1476 // newkey copy bit shifting [1, 7], parity bit shifting 0 |
|
1477 |
|
1478 // Second octet |
|
1479 // key bit shifting for second octet [2, 7] and for first octet 0 |
|
1480 // newkey copy bit shifting [1, 7], parity bit shifting 0 |
|
1481 |
|
1482 // Third octet |
|
1483 // key bit shifting for second octet [3, 7] and for first octet [0, 1} |
|
1484 // newkey copy bit shifting [1, 7], parity bit shifting 0 |
|
1485 |
|
1486 // bit no: 7 6 5 4 3 2 1 0, 0 = parity bit |
|
1487 { |
|
1488 int newkey_byte, newkey_bit, newkey_bit_shifting, |
|
1489 key_bit_no, key_byte, key_bit_shifting, bit_counter; |
|
1490 |
|
1491 for (newkey_byte = 0; newkey_byte < 8; newkey_byte++) |
|
1492 { |
|
1493 bit_counter = 0; |
|
1494 |
|
1495 for (newkey_bit = 0; newkey_bit < 7; newkey_bit++) |
|
1496 { |
|
1497 key_bit_no = newkey_byte * 7 + newkey_bit; |
|
1498 key_byte = key_bit_no / 8; |
|
1499 |
|
1500 key_bit_shifting = 7 - (key_bit_no % 8); |
|
1501 newkey_bit_shifting = 7 - (key_bit_no % 7); |
|
1502 |
|
1503 if (key[key_byte] & (1 << key_bit_shifting)) // If bit is 1... |
|
1504 { |
|
1505 newkey[newkey_byte] |= (1 << newkey_bit_shifting); // ...set bit to 1 |
|
1506 bit_counter++; |
|
1507 } |
|
1508 } |
|
1509 |
|
1510 if (bit_counter % 2 == 0) // If even number of bits... |
|
1511 { |
|
1512 // Add parity bit |
|
1513 newkey[newkey_byte] |= 1; // ...set the 1st bit to 1 |
|
1514 } |
|
1515 } |
|
1516 } |
|
1517 |
|
1518 // Copy key three times into triple size key because we are internally using 3des instead of des |
|
1519 // des: Ek == 3des: Ek3(Dk2(Ek1)) when k == k1 == k2 == k3 |
|
1520 m_am_tools->memmove(newkey + EAP_MSCHAPV2_DES_KEY_SIZE, newkey, EAP_MSCHAPV2_DES_KEY_SIZE); |
|
1521 m_am_tools->memmove(newkey + 2 * EAP_MSCHAPV2_DES_KEY_SIZE, newkey, EAP_MSCHAPV2_DES_KEY_SIZE); |
|
1522 |
|
1523 eap_status_e status; |
|
1524 |
|
1525 crypto_3des_ede_c des(m_am_tools); |
|
1526 |
|
1527 if (is_encrypt) |
|
1528 { |
|
1529 status = des.set_encryption_key(newkey, 3 * EAP_MSCHAPV2_DES_KEY_SIZE); |
|
1530 |
|
1531 if (status != eap_status_ok) |
|
1532 { |
|
1533 delete [] newkey; |
|
1534 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1535 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1536 } |
|
1537 |
|
1538 status = des.encrypt_block(data_in, data_out, EAP_MSCHAPV2_DES_BLOCK_SIZE); |
|
1539 } |
|
1540 |
|
1541 else // Decrypt mode |
|
1542 { |
|
1543 status = des.set_decryption_key(newkey, 3 * EAP_MSCHAPV2_DES_KEY_SIZE); |
|
1544 if (status != eap_status_ok) |
|
1545 { |
|
1546 delete [] newkey; |
|
1547 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1548 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1549 } |
|
1550 |
|
1551 status = des.decrypt_block(data_in, data_out, EAP_MSCHAPV2_DES_BLOCK_SIZE); |
|
1552 } |
|
1553 |
|
1554 delete [] newkey; |
|
1555 |
|
1556 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1557 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1558 } |
|
1559 |
|
1560 //-------------------------------------------------- |
|
1561 |
|
1562 static const u8_t eap_type_mschapv2_magic1a[] = { |
|
1563 0x4D, 0x61, 0x67, 0x69, 0x63, 0x20, 0x73, 0x65, 0x72, 0x76, |
|
1564 0x65, 0x72, 0x20, 0x74, 0x6F, 0x20, 0x63, 0x6C, 0x69, 0x65, |
|
1565 0x6E, 0x74, 0x20, 0x73, 0x69, 0x67, 0x6E, 0x69, 0x6E, 0x67, |
|
1566 0x20, 0x63, 0x6F, 0x6E, 0x73, 0x74, 0x61, 0x6E, 0x74 }; |
|
1567 |
|
1568 static const u8_t eap_type_mschapv2_magic2a[] = { |
|
1569 0x50, 0x61, 0x64, 0x20, 0x74, 0x6F, 0x20, 0x6D, 0x61, 0x6B, |
|
1570 0x65, 0x20, 0x69, 0x74, 0x20, 0x64, 0x6F, 0x20, 0x6D, 0x6F, |
|
1571 0x72, 0x65, 0x20, 0x74, 0x68, 0x61, 0x6E, 0x20, 0x6F, 0x6E, |
|
1572 0x65, 0x20, 0x69, 0x74, 0x65, 0x72, 0x61, 0x74, 0x69, 0x6F, |
|
1573 0x6E }; |
|
1574 |
|
1575 eap_status_e eap_type_mschapv2_c::generate_authenticator_response( |
|
1576 const u8_t * const password_hash_hash, |
|
1577 const u8_t * const nt_response, |
|
1578 const u8_t * const peer_challenge, |
|
1579 const u8_t * const authenticator_challenge, |
|
1580 const u8_t * const username, |
|
1581 const u32_t username_size, |
|
1582 u8_t * const authenticator_response) |
|
1583 { |
|
1584 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1585 |
|
1586 EAP_TRACE_DEBUG( |
|
1587 m_am_tools, |
|
1588 TRACE_FLAGS_DEFAULT, |
|
1589 (EAPL("eap_type_mschapv2_c::generate_authenticator_response(): this = 0x%08x\n"), |
|
1590 this)); |
|
1591 |
|
1592 if (!password_hash_hash |
|
1593 || !nt_response |
|
1594 || !peer_challenge |
|
1595 || !authenticator_challenge |
|
1596 || !username |
|
1597 || username_size == 0 |
|
1598 || username_size > EAP_MSCHAPV2_USERNAME_MAX_SIZE |
|
1599 || !authenticator_response) |
|
1600 { |
|
1601 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1602 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); |
|
1603 } |
|
1604 crypto_sha1_c sha1(m_am_tools); |
|
1605 |
|
1606 eap_status_e status = sha1.hash_init(); |
|
1607 if (status != eap_status_ok) |
|
1608 { |
|
1609 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1610 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1611 } |
|
1612 |
|
1613 { |
|
1614 status = sha1.hash_update(password_hash_hash, EAP_MSCHAPV2_MD4_DIGEST_SIZE); |
|
1615 if (status != eap_status_ok) |
|
1616 { |
|
1617 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1618 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1619 } |
|
1620 } |
|
1621 |
|
1622 status = sha1.hash_update(nt_response, EAP_MSCHAPV2_NT_RESPONSE_SIZE); |
|
1623 if (status != eap_status_ok) |
|
1624 { |
|
1625 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1626 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1627 } |
|
1628 |
|
1629 status = sha1.hash_update(eap_type_mschapv2_magic1a, sizeof(eap_type_mschapv2_magic1a)); |
|
1630 if (status != eap_status_ok) |
|
1631 { |
|
1632 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1633 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1634 } |
|
1635 |
|
1636 u8_t * const digest = new u8_t[EAP_MSCHAPV2_SHA1_DIGEST_SIZE]; |
|
1637 if (!digest) |
|
1638 { |
|
1639 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1640 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1641 } |
|
1642 |
|
1643 status = sha1.hash_final(digest, 0); |
|
1644 |
|
1645 if (status != eap_status_ok) |
|
1646 { |
|
1647 delete [] digest; |
|
1648 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1649 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1650 } |
|
1651 |
|
1652 u8_t * const challenge = new u8_t[EAP_MSCHAPV2_CHALLENGE_HASH_SIZE]; |
|
1653 if (!challenge) |
|
1654 { |
|
1655 delete [] digest; |
|
1656 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1657 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1658 } |
|
1659 |
|
1660 status = challenge_hash( |
|
1661 peer_challenge, |
|
1662 authenticator_challenge, |
|
1663 username, |
|
1664 username_size, |
|
1665 challenge); |
|
1666 |
|
1667 if (status != eap_status_ok) |
|
1668 { |
|
1669 delete [] digest; |
|
1670 delete [] challenge; |
|
1671 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1672 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1673 } |
|
1674 |
|
1675 sha1.hash_cleanup(); |
|
1676 |
|
1677 status = sha1.hash_init(); |
|
1678 if (status != eap_status_ok) |
|
1679 { |
|
1680 delete [] digest; |
|
1681 delete [] challenge; |
|
1682 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1683 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1684 } |
|
1685 |
|
1686 status = sha1.hash_update(digest, EAP_MSCHAPV2_SHA1_DIGEST_SIZE); |
|
1687 |
|
1688 if (status != eap_status_ok) |
|
1689 { |
|
1690 delete [] digest; |
|
1691 delete [] challenge; |
|
1692 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1693 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1694 } |
|
1695 |
|
1696 status = sha1.hash_update(challenge, EAP_MSCHAPV2_CHALLENGE_HASH_SIZE); |
|
1697 |
|
1698 delete [] challenge; |
|
1699 |
|
1700 if (status != eap_status_ok) |
|
1701 { |
|
1702 delete [] digest; |
|
1703 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1704 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1705 } |
|
1706 |
|
1707 status = sha1.hash_update(eap_type_mschapv2_magic2a, sizeof(eap_type_mschapv2_magic2a)); |
|
1708 if (status != eap_status_ok) |
|
1709 { |
|
1710 delete [] digest; |
|
1711 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1712 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1713 } |
|
1714 |
|
1715 status = sha1.hash_final(digest, 0); |
|
1716 |
|
1717 if (status != eap_status_ok) |
|
1718 { |
|
1719 delete [] digest; |
|
1720 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1721 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1722 } |
|
1723 |
|
1724 m_am_tools->memmove(authenticator_response, "S=", 2); |
|
1725 u32_t length = EAP_MSCHAPV2_SHA1_DIGEST_SIZE * 2; |
|
1726 m_am_tools->convert_bytes_to_hex_ascii( |
|
1727 digest, |
|
1728 EAP_MSCHAPV2_SHA1_DIGEST_SIZE, |
|
1729 authenticator_response + 2, |
|
1730 &length); |
|
1731 |
|
1732 m_am_tools->convert_ascii_to_uppercase(authenticator_response + 2, length); |
|
1733 |
|
1734 delete [] digest; |
|
1735 |
|
1736 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1737 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
1738 } |
|
1739 |
|
1740 //-------------------------------------------------- |
|
1741 |
|
1742 eap_status_e eap_type_mschapv2_c::check_authenticator_response( |
|
1743 const eap_variable_data_c * const password_hash_hash, |
|
1744 const u8_t * const nt_response, |
|
1745 const u8_t * const peer_challenge, |
|
1746 const u8_t * const authenticator_challenge, |
|
1747 const u8_t * const username, |
|
1748 const u32_t username_size, |
|
1749 const u8_t * const received_response, |
|
1750 bool & response_ok) |
|
1751 { |
|
1752 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1753 |
|
1754 EAP_TRACE_DEBUG( |
|
1755 m_am_tools, |
|
1756 TRACE_FLAGS_DEFAULT, |
|
1757 (EAPL("eap_type_mschapv2_c::check_authenticator_response(): this = 0x%08x\n"), |
|
1758 this)); |
|
1759 |
|
1760 if (!password_hash_hash |
|
1761 || password_hash_hash->get_data_length() < EAP_MSCHAPV2_MD4_DIGEST_SIZE |
|
1762 || !nt_response |
|
1763 || !peer_challenge |
|
1764 || !authenticator_challenge |
|
1765 || !username |
|
1766 || username_size == 0 |
|
1767 || username_size > EAP_MSCHAPV2_USERNAME_MAX_SIZE |
|
1768 || !received_response) |
|
1769 { |
|
1770 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1771 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); |
|
1772 } |
|
1773 |
|
1774 response_ok = false; |
|
1775 |
|
1776 u8_t * const response = new u8_t[EAP_MSCHAPV2_AUTHENTICATOR_RESPONSE_SIZE]; |
|
1777 if (!response) |
|
1778 { |
|
1779 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1780 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1781 } |
|
1782 |
|
1783 eap_status_e status = generate_authenticator_response( |
|
1784 password_hash_hash->get_data(), |
|
1785 nt_response, |
|
1786 peer_challenge, |
|
1787 authenticator_challenge, |
|
1788 username, |
|
1789 username_size, |
|
1790 response); |
|
1791 if (status != eap_status_ok) |
|
1792 { |
|
1793 delete [] response; |
|
1794 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1795 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1796 } |
|
1797 |
|
1798 EAP_TRACE_DATA_DEBUG( |
|
1799 m_am_tools, |
|
1800 TRACE_FLAGS_DEFAULT, |
|
1801 (EAPL("client_handle_success_request(): response"), |
|
1802 response, |
|
1803 EAP_MSCHAPV2_AUTHENTICATOR_RESPONSE_SIZE)); |
|
1804 |
|
1805 EAP_TRACE_DATA_DEBUG( |
|
1806 m_am_tools, |
|
1807 TRACE_FLAGS_DEFAULT, |
|
1808 (EAPL("client_handle_success_request(): received_response"), |
|
1809 received_response, |
|
1810 EAP_MSCHAPV2_AUTHENTICATOR_RESPONSE_SIZE)); |
|
1811 |
|
1812 if (m_am_tools->memcmp( |
|
1813 response, |
|
1814 received_response, |
|
1815 EAP_MSCHAPV2_AUTHENTICATOR_RESPONSE_SIZE) |
|
1816 == 0) |
|
1817 { |
|
1818 response_ok = true; |
|
1819 } |
|
1820 else |
|
1821 { |
|
1822 #if defined(USE_FAST_EAP_TYPE) |
|
1823 if (m_use_EAP_FAST_challenge == true) |
|
1824 { |
|
1825 (void) send_error_notification(eap_status_tunnel_compromise_error); |
|
1826 } |
|
1827 #endif //#if defined(USE_FAST_EAP_TYPE) |
|
1828 } |
|
1829 |
|
1830 delete [] response; |
|
1831 |
|
1832 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1833 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1834 } |
|
1835 |
|
1836 //-------------------------------------------------- |
|
1837 |
|
1838 eap_status_e eap_type_mschapv2_c::new_password_encrypted_with_old_nt_password_hash( |
|
1839 const eap_variable_data_c * const new_password_utf8, |
|
1840 const eap_variable_data_c * const old_password_hash, |
|
1841 u8_t * encrypted_pw_block) |
|
1842 { |
|
1843 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1844 |
|
1845 EAP_TRACE_DEBUG( |
|
1846 m_am_tools, |
|
1847 TRACE_FLAGS_DEFAULT, |
|
1848 (EAPL("eap_type_mschapv2_c::new_password_encrypted_with_old_nt_password_hash(): this = 0x%08x\n"), |
|
1849 this)); |
|
1850 |
|
1851 if (!new_password_utf8 |
|
1852 || new_password_utf8->get_data_length() > EAP_MSCHAPV2_PASSWORD_MAX_SIZE |
|
1853 || !old_password_hash |
|
1854 || !encrypted_pw_block) |
|
1855 { |
|
1856 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1857 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); |
|
1858 } |
|
1859 |
|
1860 eap_status_e status = encrypt_pw_block_with_password_hash( |
|
1861 new_password_utf8, |
|
1862 old_password_hash->get_data(), |
|
1863 encrypted_pw_block); |
|
1864 |
|
1865 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1866 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1867 } |
|
1868 |
|
1869 //-------------------------------------------------- |
|
1870 |
|
1871 eap_status_e eap_type_mschapv2_c::encrypt_pw_block_with_password_hash( |
|
1872 const eap_variable_data_c * const password_utf8, |
|
1873 const u8_t * const password_hash, |
|
1874 u8_t * pw_block) |
|
1875 { |
|
1876 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1877 |
|
1878 EAP_TRACE_DEBUG( |
|
1879 m_am_tools, |
|
1880 TRACE_FLAGS_DEFAULT, |
|
1881 (EAPL("eap_type_mschapv2_c::encrypt_pw_block_with_password_hash(): this = 0x%08x\n"), |
|
1882 this)); |
|
1883 |
|
1884 if (!password_utf8 |
|
1885 || password_utf8->get_data_length() > EAP_MSCHAPV2_PASSWORD_MAX_SIZE |
|
1886 || !password_hash |
|
1887 || !pw_block |
|
1888 || !m_rand.get_is_valid()) |
|
1889 { |
|
1890 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1891 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); |
|
1892 } |
|
1893 |
|
1894 eap_status_e status = m_rand.add_rand_seed_hw_ticks(); |
|
1895 if (status != eap_status_ok) |
|
1896 { |
|
1897 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1898 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1899 } |
|
1900 |
|
1901 status = m_rand.add_rand_seed(password_utf8->get_data(), password_utf8->get_data_length()); |
|
1902 if (status != eap_status_ok) |
|
1903 { |
|
1904 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1905 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1906 } |
|
1907 |
|
1908 pw_block_s * clear_pw_block = new pw_block_s; |
|
1909 if (!clear_pw_block) |
|
1910 { |
|
1911 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1912 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1913 } |
|
1914 |
|
1915 eap_variable_data_c tmp_password_unicode(m_am_tools); |
|
1916 status = m_am_tools->convert_utf8_to_unicode(tmp_password_unicode, *password_utf8); |
|
1917 if (status != eap_status_ok) |
|
1918 { |
|
1919 delete clear_pw_block; |
|
1920 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1921 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1922 } |
|
1923 |
|
1924 u32_t pw_offset = EAP_MSCHAPV2_PASSWORD_MAX_SIZE - tmp_password_unicode.get_data_length(); |
|
1925 |
|
1926 // Fill begin of clear_pw_block with random octet values |
|
1927 status = m_rand.get_rand_bytes(clear_pw_block->password, pw_offset); |
|
1928 if (status != eap_status_ok) |
|
1929 { |
|
1930 delete clear_pw_block; |
|
1931 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1932 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1933 } |
|
1934 |
|
1935 // Copy password to end of clear_pw_block |
|
1936 m_am_tools->memmove( |
|
1937 clear_pw_block->password + pw_offset, |
|
1938 tmp_password_unicode.get_data(), |
|
1939 tmp_password_unicode.get_data_length()); |
|
1940 |
|
1941 // Password size must be little endian |
|
1942 #ifdef EAP_BIG_ENDIAN |
|
1943 u8_t * pw_bytes = reinterpret_cast<u8_t *>(&pw_size); |
|
1944 u8_t tmp; |
|
1945 |
|
1946 tmp = bytes[0]; |
|
1947 bytes[0] = bytes[3]; |
|
1948 bytes[3] = tmp; |
|
1949 tmp = bytes[1]; |
|
1950 bytes[1] = bytes[2]; |
|
1951 bytes[2] = tmp; |
|
1952 #endif |
|
1953 |
|
1954 clear_pw_block->password_length = tmp_password_unicode.get_data_length(); |
|
1955 |
|
1956 status = rc4_encrypt( |
|
1957 reinterpret_cast<u8_t *>(clear_pw_block), |
|
1958 sizeof(pw_block_s), |
|
1959 password_hash, |
|
1960 EAP_MSCHAPV2_MD4_DIGEST_SIZE, |
|
1961 pw_block); |
|
1962 |
|
1963 delete clear_pw_block; |
|
1964 |
|
1965 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1966 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1967 } |
|
1968 |
|
1969 //-------------------------------------------------- |
|
1970 |
|
1971 eap_status_e eap_type_mschapv2_c::rc4_encrypt( |
|
1972 const u8_t * const clear, |
|
1973 const u32_t clear_length, |
|
1974 const u8_t * const key, |
|
1975 const u32_t key_length, |
|
1976 u8_t * const cypher) |
|
1977 { |
|
1978 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1979 |
|
1980 EAP_TRACE_DEBUG( |
|
1981 m_am_tools, |
|
1982 TRACE_FLAGS_DEFAULT, |
|
1983 (EAPL("eap_type_mschapv2_c::rc4_encrypt(): this = 0x%08x\n"), |
|
1984 this)); |
|
1985 |
|
1986 if (!clear |
|
1987 || clear_length == 0 |
|
1988 || !key |
|
1989 || key_length == 0 |
|
1990 || !cypher) |
|
1991 { |
|
1992 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1993 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); |
|
1994 } |
|
1995 |
|
1996 eap_variable_data_c v_key(m_am_tools); |
|
1997 |
|
1998 eap_status_e status = v_key.set_buffer(key, key_length, false, false); // Cannot fail |
|
1999 if (status != eap_status_ok |
|
2000 || v_key.get_is_valid() == false) |
|
2001 { |
|
2002 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2003 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
2004 } |
|
2005 |
|
2006 crypto_rc4_c rc4(m_am_tools); |
|
2007 |
|
2008 status = rc4.set_key(&v_key); |
|
2009 |
|
2010 if (status != eap_status_ok) |
|
2011 { |
|
2012 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2013 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2014 } |
|
2015 |
|
2016 status = rc4.encrypt_data(clear, cypher, clear_length); |
|
2017 |
|
2018 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2019 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2020 } |
|
2021 |
|
2022 //-------------------------------------------------- |
|
2023 |
|
2024 eap_status_e eap_type_mschapv2_c::old_nt_password_hash_encrypted_with_new_nt_password_hash( |
|
2025 const eap_variable_data_c * const new_password_hash, |
|
2026 const eap_variable_data_c * const old_password_hash, |
|
2027 eap_variable_data_c * const encrypted_password_hash) |
|
2028 { |
|
2029 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2030 |
|
2031 EAP_TRACE_DEBUG( |
|
2032 m_am_tools, |
|
2033 TRACE_FLAGS_DEFAULT, |
|
2034 (EAPL("eap_type_mschapv2_c::old_nt_password_hash_encrypted_with_new_nt_password_hash(): this = 0x%08x\n"), |
|
2035 this)); |
|
2036 |
|
2037 if (!new_password_hash |
|
2038 || !old_password_hash |
|
2039 || !encrypted_password_hash) |
|
2040 { |
|
2041 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2042 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); |
|
2043 } |
|
2044 |
|
2045 eap_status_e status = nt_password_hash_encrypted_with_block( |
|
2046 old_password_hash, |
|
2047 new_password_hash, |
|
2048 encrypted_password_hash); |
|
2049 |
|
2050 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2051 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2052 } |
|
2053 |
|
2054 //-------------------------------------------------- |
|
2055 |
|
2056 eap_status_e eap_type_mschapv2_c::nt_password_hash_encrypted_with_block( |
|
2057 const eap_variable_data_c * const password_hash, |
|
2058 const eap_variable_data_c * const block, |
|
2059 eap_variable_data_c * const cypher) |
|
2060 { |
|
2061 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2062 |
|
2063 EAP_TRACE_DEBUG( |
|
2064 m_am_tools, |
|
2065 TRACE_FLAGS_DEFAULT, |
|
2066 (EAPL("eap_type_mschapv2_c::nt_password_hash_encrypted_with_block(): this = 0x%08x\n"), |
|
2067 this)); |
|
2068 |
|
2069 if (!password_hash |
|
2070 || !block |
|
2071 || !cypher) |
|
2072 { |
|
2073 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2074 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); |
|
2075 } |
|
2076 |
|
2077 eap_status_e status = cypher->set_buffer_length(EAP_MSCHAPV2_MD4_DIGEST_SIZE); |
|
2078 if (status != eap_status_ok) |
|
2079 { |
|
2080 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2081 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2082 } |
|
2083 |
|
2084 status = cypher->set_data_length(EAP_MSCHAPV2_MD4_DIGEST_SIZE); |
|
2085 if (status != eap_status_ok) |
|
2086 { |
|
2087 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2088 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2089 } |
|
2090 |
|
2091 status = des_encrypt( |
|
2092 password_hash->get_data(), // 1st 8-octets password_hash |
|
2093 block->get_data(), // 1st 7-octets block |
|
2094 cypher->get_data(EAP_MSCHAPV2_DES_BLOCK_SIZE)); // giving 1st 8-octets cypher |
|
2095 |
|
2096 if (status != eap_status_ok) |
|
2097 { |
|
2098 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2099 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2100 } |
|
2101 |
|
2102 status = des_encrypt( |
|
2103 password_hash->get_data_offset(8,8), // 2nd 8-octets password_hash |
|
2104 block->get_data_offset(7,7), // 2nd 7-octets block |
|
2105 cypher->get_data_offset(8,EAP_MSCHAPV2_DES_BLOCK_SIZE)); // giving 2nd 8-octets cypher |
|
2106 |
|
2107 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2108 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2109 } |
|
2110 |
|
2111 //-------------------------------------------------- |
|
2112 |
|
2113 eap_status_e eap_type_mschapv2_c::generate_session_key( |
|
2114 eap_master_session_key_c * const key) |
|
2115 { |
|
2116 EAP_TRACE_DEBUG( |
|
2117 m_am_tools, |
|
2118 TRACE_FLAGS_DEFAULT, |
|
2119 (EAPL("eap_type_mschapv2_c::generate_session_key(): this = 0x%08x\n"), |
|
2120 this)); |
|
2121 |
|
2122 eap_status_e status(eap_status_ok); |
|
2123 |
|
2124 eap_variable_data_c master_key(m_am_tools); |
|
2125 if (master_key.get_is_valid() == false) |
|
2126 { |
|
2127 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2128 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
2129 } |
|
2130 |
|
2131 crypto_nt_hash_c nt_hash(m_am_tools); |
|
2132 if (nt_hash.get_is_valid() == false) |
|
2133 { |
|
2134 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2135 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
2136 } |
|
2137 |
|
2138 eap_variable_data_c nt_response(m_am_tools); |
|
2139 if (nt_response.get_is_valid() == false) |
|
2140 { |
|
2141 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2142 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
2143 } |
|
2144 |
|
2145 status = nt_response.set_buffer( |
|
2146 m_nt_response, |
|
2147 EAP_MSCHAPV2_NT_RESPONSE_SIZE, |
|
2148 false, |
|
2149 true); |
|
2150 if (status != eap_status_ok) |
|
2151 { |
|
2152 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2153 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2154 } |
|
2155 |
|
2156 status = nt_hash.get_master_key( |
|
2157 &m_password_hash_hash, |
|
2158 &nt_response, |
|
2159 &master_key, |
|
2160 EAP_MSCHAPV2_MASTER_KEY_SIZE); |
|
2161 if (status != eap_status_ok) |
|
2162 { |
|
2163 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2164 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2165 } |
|
2166 |
|
2167 EAP_TRACE_DATA_DEBUG( |
|
2168 m_am_tools, |
|
2169 TRACE_FLAGS_DEFAULT, |
|
2170 (EAPL("EAP_type_MSCHAPV2: client_send_challenge_response(), master_key"), |
|
2171 master_key.get_data(), |
|
2172 master_key.get_data_length())); |
|
2173 |
|
2174 eap_variable_data_c asymmetric_start_key(m_am_tools); |
|
2175 |
|
2176 if (asymmetric_start_key.get_is_valid() == false) |
|
2177 { |
|
2178 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2179 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
2180 } |
|
2181 |
|
2182 |
|
2183 #if defined(USE_FAST_EAP_TYPE) |
|
2184 if (m_use_EAP_FAST_full_key == true) |
|
2185 { |
|
2186 eap_variable_data_c session_key_2(m_am_tools); |
|
2187 |
|
2188 if (session_key_2.get_is_valid() == false) |
|
2189 { |
|
2190 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2191 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
2192 } |
|
2193 |
|
2194 status = nt_hash.get_asymmetric_start_key( |
|
2195 &master_key, |
|
2196 &asymmetric_start_key, |
|
2197 EAP_MSCHAPV2_MASTER_KEY_SIZE, |
|
2198 false, |
|
2199 false); |
|
2200 if (status != eap_status_ok) |
|
2201 { |
|
2202 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2203 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2204 } |
|
2205 |
|
2206 EAP_TRACE_DATA_DEBUG( |
|
2207 m_am_tools, |
|
2208 TRACE_FLAGS_DEFAULT, |
|
2209 (EAPL("EAP_type_MSCHAPV2: client_send_challenge_response(), asymmetric_start_key_1"), |
|
2210 asymmetric_start_key.get_data(), |
|
2211 asymmetric_start_key.get_data_length())); |
|
2212 |
|
2213 status = key->set_copy_of_buffer(&asymmetric_start_key); |
|
2214 if (status != eap_status_ok) |
|
2215 { |
|
2216 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2217 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2218 } |
|
2219 |
|
2220 status = nt_hash.get_asymmetric_start_key( |
|
2221 &master_key, |
|
2222 &asymmetric_start_key, |
|
2223 EAP_MSCHAPV2_MASTER_KEY_SIZE, |
|
2224 true, |
|
2225 false); |
|
2226 if (status != eap_status_ok) |
|
2227 { |
|
2228 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2229 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2230 } |
|
2231 |
|
2232 EAP_TRACE_DATA_DEBUG( |
|
2233 m_am_tools, |
|
2234 TRACE_FLAGS_DEFAULT, |
|
2235 (EAPL("EAP_type_MSCHAPV2: client_send_challenge_response(), asymmetric_start_key_2"), |
|
2236 asymmetric_start_key.get_data(), |
|
2237 asymmetric_start_key.get_data_length())); |
|
2238 |
|
2239 status = key->add_data(&asymmetric_start_key); |
|
2240 if (status != eap_status_ok) |
|
2241 { |
|
2242 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2243 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2244 } |
|
2245 |
|
2246 } |
|
2247 else |
|
2248 #endif //#if defined(USE_FAST_EAP_TYPE) |
|
2249 { |
|
2250 status = nt_hash.get_asymmetric_start_key( |
|
2251 &master_key, |
|
2252 &asymmetric_start_key, |
|
2253 EAP_MSCHAPV2_MASTER_KEY_SIZE, |
|
2254 true, |
|
2255 false); |
|
2256 if (status != eap_status_ok) |
|
2257 { |
|
2258 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2259 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2260 } |
|
2261 |
|
2262 EAP_TRACE_DATA_DEBUG( |
|
2263 m_am_tools, |
|
2264 TRACE_FLAGS_DEFAULT, |
|
2265 (EAPL("EAP_type_MSCHAPV2: client_send_challenge_response(), asymmetric_start_key_2"), |
|
2266 asymmetric_start_key.get_data(), |
|
2267 asymmetric_start_key.get_data_length())); |
|
2268 |
|
2269 status = key->set_copy_of_buffer(&asymmetric_start_key); |
|
2270 if (status != eap_status_ok) |
|
2271 { |
|
2272 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2273 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2274 } |
|
2275 } |
|
2276 |
|
2277 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2278 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2279 } |
|
2280 |
|
2281 // End of File |