|
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 76 |
|
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 |
|
29 #include "eap_am_memory.h" |
|
30 #include "eap_tools.h" |
|
31 #include "eap_type_gsmsim.h" |
|
32 #include "eap_type_gsmsim_header.h" |
|
33 #include "eap_type_gsmsim_payloads.h" |
|
34 #include "eap_type_gsmsim_mac_attributes.h" |
|
35 #include "abs_eap_am_type_gsmsim.h" |
|
36 #include "eap_crypto_api.h" |
|
37 #include "eap_state_notification.h" |
|
38 #include "abs_eap_am_mutex.h" |
|
39 #include "eap_automatic_variable.h" |
|
40 #include "eap_type_gsmsim_header.h" |
|
41 #include "eap_am_type_gsmsim.h" |
|
42 |
|
43 |
|
44 //-------------------------------------------------- |
|
45 |
|
46 /** @file */ |
|
47 |
|
48 //-------------------------------------------------- |
|
49 |
|
50 // |
|
51 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::generate_nai( |
|
52 eap_variable_data_c * const new_nai, |
|
53 const bool use_manual_default_realm, |
|
54 const eap_variable_data_c * const nai_realm, |
|
55 const eap_variable_data_c * const id_IMSI_or_pseudonym, |
|
56 const bool id_is_imsi, |
|
57 const eap_variable_data_c * const IMSI, |
|
58 const eap_variable_data_c * const automatic_realm, |
|
59 const u32_t length_of_mnc) |
|
60 { |
|
61 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
62 |
|
63 if (id_IMSI_or_pseudonym == 0 |
|
64 || id_IMSI_or_pseudonym->get_is_valid_data() == false) |
|
65 { |
|
66 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
67 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); |
|
68 } |
|
69 |
|
70 eap_status_e status = eap_status_not_supported; |
|
71 |
|
72 status = new_nai->init(id_IMSI_or_pseudonym->get_data_length()+1u); |
|
73 if (status != eap_status_ok) |
|
74 { |
|
75 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
76 return EAP_STATUS_RETURN(m_am_tools, status); |
|
77 } |
|
78 new_nai->set_is_valid(); |
|
79 |
|
80 eap_variable_data_c local_username(m_am_tools); |
|
81 status = local_username.set_buffer_length(id_IMSI_or_pseudonym->get_data_length()); |
|
82 if (status != eap_status_ok) |
|
83 { |
|
84 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
85 return EAP_STATUS_RETURN(m_am_tools, status); |
|
86 } |
|
87 local_username.set_data_length(id_IMSI_or_pseudonym->get_data_length()); |
|
88 |
|
89 m_am_tools->memmove( |
|
90 local_username.get_data(id_IMSI_or_pseudonym->get_data_length()), |
|
91 id_IMSI_or_pseudonym->get_data(), |
|
92 id_IMSI_or_pseudonym->get_data_length()); |
|
93 |
|
94 new_nai->set_data_length(0u); |
|
95 |
|
96 if (id_is_imsi == true) |
|
97 { |
|
98 // Note the first octet is reserved for IMSI prefix. |
|
99 status = new_nai->add_data(GSMSIM_IMSI_PREFIX_CHARACTER, 1u); |
|
100 if (status != eap_status_ok) |
|
101 { |
|
102 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
103 return EAP_STATUS_RETURN(m_am_tools, status); |
|
104 } |
|
105 } |
|
106 |
|
107 // This could be IMSI or pseudonym. |
|
108 status = new_nai->add_data(&local_username); |
|
109 if (status != eap_status_ok) |
|
110 { |
|
111 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
112 return EAP_STATUS_RETURN(m_am_tools, status); |
|
113 } |
|
114 |
|
115 if (use_manual_default_realm == true |
|
116 && nai_realm != 0 |
|
117 && nai_realm->get_is_valid_data() == true) |
|
118 { |
|
119 if (nai_realm->get_data_length() > 0ul) |
|
120 { |
|
121 status = new_nai->add_data(GSMSIM_AT_CHARACTER, 1u); |
|
122 if (status != eap_status_ok) |
|
123 { |
|
124 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
125 return EAP_STATUS_RETURN(m_am_tools, status); |
|
126 } |
|
127 } |
|
128 |
|
129 status = new_nai->add_data(nai_realm); |
|
130 if (status != eap_status_ok) |
|
131 { |
|
132 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
133 return EAP_STATUS_RETURN(m_am_tools, status); |
|
134 } |
|
135 } |
|
136 else if (IMSI != 0 |
|
137 && IMSI->get_is_valid_data() == true |
|
138 && IMSI->get_data_length() >= EAP_TYPE_GSMSIM_MINIMUM_IMSI_LENGTH) |
|
139 { |
|
140 status = new_nai->add_data(GSMSIM_AT_CHARACTER, 1u); |
|
141 if (status != eap_status_ok) |
|
142 { |
|
143 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
144 return EAP_STATUS_RETURN(m_am_tools, status); |
|
145 } |
|
146 |
|
147 if (automatic_realm != 0 |
|
148 && automatic_realm->get_is_valid_data() == true) |
|
149 { |
|
150 // We must use automatic realm. |
|
151 |
|
152 status = new_nai->add_data(automatic_realm); |
|
153 if (status != eap_status_ok) |
|
154 { |
|
155 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
156 return EAP_STATUS_RETURN(m_am_tools, status); |
|
157 } |
|
158 } |
|
159 else |
|
160 { |
|
161 // We must use automatic realm (Example: "wlan.mnc456.mcc123.3gppnetwork.org"). |
|
162 |
|
163 status = new_nai->add_data(GSMSIM_OWLAN_ORG_PREFIX_STRING, GSMSIM_OWLAN_ORG_PREFIX_STRING_LENGTH); |
|
164 if (status != eap_status_ok) |
|
165 { |
|
166 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
167 return EAP_STATUS_RETURN(m_am_tools, status); |
|
168 } |
|
169 |
|
170 status = new_nai->add_data(GSMSIM_OWLAN_DOT_STRING, GSMSIM_OWLAN_DOT_STRING_LENGTH); |
|
171 if (status != eap_status_ok) |
|
172 { |
|
173 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
174 return EAP_STATUS_RETURN(m_am_tools, status); |
|
175 } |
|
176 |
|
177 status = new_nai->add_data(GSMSIM_OWLAN_MNC_STRING, GSMSIM_OWLAN_MNC_STRING_LENGTH); |
|
178 if (status != eap_status_ok) |
|
179 { |
|
180 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
181 return EAP_STATUS_RETURN(m_am_tools, status); |
|
182 } |
|
183 |
|
184 // MNC part. |
|
185 if (length_of_mnc == EAP_TYPE_GSMSIM_MNC_LENGTH_2_BYTES) |
|
186 { |
|
187 // Add zero digit. |
|
188 u8_t zero = '0'; |
|
189 status = new_nai->add_data(&zero, sizeof(zero)); |
|
190 if (status != eap_status_ok) |
|
191 { |
|
192 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
193 return EAP_STATUS_RETURN(m_am_tools, status); |
|
194 } |
|
195 } |
|
196 status = new_nai->add_data(IMSI->get_data_offset(EAP_TYPE_GSMSIM_MNC_OFFSET, length_of_mnc), length_of_mnc); |
|
197 if (status != eap_status_ok) |
|
198 { |
|
199 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
200 return EAP_STATUS_RETURN(m_am_tools, status); |
|
201 } |
|
202 |
|
203 status = new_nai->add_data(GSMSIM_OWLAN_DOT_STRING, GSMSIM_OWLAN_DOT_STRING_LENGTH); |
|
204 if (status != eap_status_ok) |
|
205 { |
|
206 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
207 return EAP_STATUS_RETURN(m_am_tools, status); |
|
208 } |
|
209 |
|
210 status = new_nai->add_data(GSMSIM_OWLAN_MCC_STRING, GSMSIM_OWLAN_MCC_STRING_LENGTH); |
|
211 if (status != eap_status_ok) |
|
212 { |
|
213 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
214 return EAP_STATUS_RETURN(m_am_tools, status); |
|
215 } |
|
216 |
|
217 // MCC part is in index 0 and it is 3 bytes long. |
|
218 status = new_nai->add_data(IMSI->get_data_offset(EAP_TYPE_GSMSIM_MCC_OFFSET, EAP_TYPE_GSMSIM_MCC_LENGTH), EAP_TYPE_GSMSIM_MCC_LENGTH); |
|
219 if (status != eap_status_ok) |
|
220 { |
|
221 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
222 return EAP_STATUS_RETURN(m_am_tools, status); |
|
223 } |
|
224 |
|
225 status = new_nai->add_data(GSMSIM_OWLAN_DOT_STRING, GSMSIM_OWLAN_DOT_STRING_LENGTH); |
|
226 if (status != eap_status_ok) |
|
227 { |
|
228 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
229 return EAP_STATUS_RETURN(m_am_tools, status); |
|
230 } |
|
231 |
|
232 status = new_nai->add_data(GSMSIM_OWLAN_ORG_STRING, GSMSIM_OWLAN_ORG_STRING_LENGTH); |
|
233 if (status != eap_status_ok) |
|
234 { |
|
235 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
236 return EAP_STATUS_RETURN(m_am_tools, status); |
|
237 } |
|
238 } |
|
239 } |
|
240 |
|
241 EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("new_nai"), |
|
242 new_nai->get_data(), |
|
243 new_nai->get_data_length())); |
|
244 |
|
245 if (new_nai->get_data_length() < sizeof(u8_t)) |
|
246 { |
|
247 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
248 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_nai); |
|
249 } |
|
250 |
|
251 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
252 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
253 } |
|
254 |
|
255 //-------------------------------------------------- |
|
256 |
|
257 // |
|
258 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::query_SIM_IMSI_or_pseudonym_or_reauthentication_id( |
|
259 eap_variable_data_c * const IMSI, |
|
260 eap_variable_data_c * const pseudonym_identity, |
|
261 eap_variable_data_c * const reauthentication_identity, |
|
262 eap_variable_data_c * const automatic_realm, ///< If this is not used, do not add any data to this parameter. |
|
263 u32_t * const length_of_mnc, |
|
264 const bool must_be_synchronous, |
|
265 const gsmsim_payload_AT_type_e required_identity, |
|
266 const eap_type_gsmsim_complete_e required_completion, |
|
267 const u8_t received_eap_identifier) |
|
268 { |
|
269 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
270 |
|
271 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
272 |
|
273 eap_status_e status = eap_status_process_general_error; |
|
274 |
|
275 save_current_state(); |
|
276 set_state(eap_type_gsmsim_state_pending_identity_query); |
|
277 |
|
278 status = m_am_type_gsmsim->query_SIM_IMSI_or_pseudonym_or_reauthentication_id( |
|
279 must_be_synchronous, |
|
280 IMSI, |
|
281 pseudonym_identity, |
|
282 reauthentication_identity, |
|
283 automatic_realm, |
|
284 length_of_mnc, |
|
285 required_identity, |
|
286 required_completion, |
|
287 received_eap_identifier); |
|
288 |
|
289 if (status == eap_status_pending_request) |
|
290 { |
|
291 // This is pending query, that will be completed by complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() call. |
|
292 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
293 return EAP_STATUS_RETURN(m_am_tools, status); |
|
294 } |
|
295 else if (status == eap_status_completed_request) |
|
296 { |
|
297 // This is already completed by complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() call. |
|
298 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
299 return EAP_STATUS_RETURN(m_am_tools, status); |
|
300 } |
|
301 else if (status != eap_status_ok |
|
302 && status != eap_status_success) |
|
303 { |
|
304 // This is an error case. |
|
305 restore_saved_previous_state(); |
|
306 |
|
307 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
308 return EAP_STATUS_RETURN(m_am_tools, status); |
|
309 } |
|
310 else if (status == eap_status_ok) |
|
311 { |
|
312 if (m_use_pseudonym_identity == false) |
|
313 { |
|
314 // We do not want use pseudonym identity. |
|
315 pseudonym_identity->reset(); |
|
316 } |
|
317 |
|
318 if (m_use_reauthentication_identity == false) |
|
319 { |
|
320 // We do not want use re-authentication identity. |
|
321 reauthentication_identity->reset(); |
|
322 } |
|
323 } |
|
324 |
|
325 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
326 return EAP_STATUS_RETURN(m_am_tools, status); |
|
327 } |
|
328 |
|
329 //-------------------------------------------------- |
|
330 |
|
331 // |
|
332 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::check_rands( |
|
333 const eap_variable_data_c * const n_rands |
|
334 ) |
|
335 { |
|
336 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
337 |
|
338 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
339 |
|
340 if ((n_rands->get_data_length() % SIM_RAND_LENGTH) != 0) |
|
341 { |
|
342 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
343 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_data_payload); |
|
344 } |
|
345 |
|
346 const u32_t rand_count = n_rands->get_data_length() / SIM_RAND_LENGTH; |
|
347 |
|
348 if (rand_count < m_minimum_rand_count) |
|
349 { |
|
350 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
351 return EAP_STATUS_RETURN(m_am_tools, eap_status_not_enough_challenges); |
|
352 } |
|
353 |
|
354 u32_t ind = 0ul; |
|
355 |
|
356 for (ind = 0ul; ind+1ul < rand_count; ind++) |
|
357 { |
|
358 const u8_t * const rand_a = n_rands->get_data_offset(ind*SIM_RAND_LENGTH, SIM_RAND_LENGTH); |
|
359 for (u32_t b_ind = ind+1ul; b_ind < rand_count; b_ind++) |
|
360 { |
|
361 const u8_t * const rand_b = n_rands->get_data_offset(b_ind*SIM_RAND_LENGTH, SIM_RAND_LENGTH); |
|
362 if (rand_a == 0 |
|
363 || rand_b == 0 |
|
364 || m_am_tools->memcmp(rand_a, rand_b, SIM_RAND_LENGTH) == 0) |
|
365 { |
|
366 // ERROR: Two equal RANDs. |
|
367 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
368 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_data_payload); |
|
369 } |
|
370 } |
|
371 } |
|
372 |
|
373 if (m_do_rand_uniqueness_check == true) |
|
374 { |
|
375 eap_status_e status = m_am_type_gsmsim->check_is_rand_unused(n_rands); |
|
376 if (status != eap_status_ok) |
|
377 { |
|
378 // ERROR: RAND is used already. |
|
379 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
380 return EAP_STATUS_RETURN(m_am_tools, eap_status_not_fresh_challenges); |
|
381 } |
|
382 } |
|
383 |
|
384 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
385 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
386 } |
|
387 |
|
388 //-------------------------------------------------- |
|
389 |
|
390 // |
|
391 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::query_SIM_kc_sres( |
|
392 const eap_variable_data_c * const n_rands, |
|
393 eap_variable_data_c * const n_kc, |
|
394 eap_variable_data_c * const n_sres |
|
395 ) |
|
396 { |
|
397 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
398 |
|
399 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
400 |
|
401 eap_status_e status = eap_status_process_general_error; |
|
402 |
|
403 status = check_rands(n_rands); |
|
404 if (status != eap_status_ok) |
|
405 { |
|
406 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
407 return EAP_STATUS_RETURN(m_am_tools, status); |
|
408 } |
|
409 |
|
410 status = m_n_rands.set_copy_of_buffer(n_rands); |
|
411 if (status != eap_status_ok) |
|
412 { |
|
413 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
414 return EAP_STATUS_RETURN(m_am_tools, status); |
|
415 } |
|
416 |
|
417 set_state(eap_type_gsmsim_state_pending_kc_sres_query); |
|
418 |
|
419 status = m_am_type_gsmsim->query_SIM_kc_sres( |
|
420 false, |
|
421 n_rands, |
|
422 n_kc, |
|
423 n_sres); |
|
424 |
|
425 if (status == eap_status_pending_request) |
|
426 { |
|
427 // This is pending query, that will be completed by complete_SIM_kc_sres() call. |
|
428 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
429 return EAP_STATUS_RETURN(m_am_tools, status); |
|
430 } |
|
431 else if (status == eap_status_completed_request) |
|
432 { |
|
433 // This is already completed by complete_SIM_kc_sres() call. |
|
434 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
435 return EAP_STATUS_RETURN(m_am_tools, status); |
|
436 } |
|
437 else if (status != eap_status_ok |
|
438 && status != eap_status_success) |
|
439 { |
|
440 // This is a error case. |
|
441 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
442 return EAP_STATUS_RETURN(m_am_tools, status); |
|
443 } |
|
444 |
|
445 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
446 return EAP_STATUS_RETURN(m_am_tools, status); |
|
447 } |
|
448 |
|
449 //-------------------------------------------------- |
|
450 |
|
451 u32_t eap_type_gsmsim_c::get_mnc_length(const u32_t mcc) |
|
452 { |
|
453 u32_t * const mcc_array = reinterpret_cast<u32_t *>(m_2_digit_mnc_map_of_mcc_of_imsi_array.get_data( |
|
454 m_2_digit_mnc_map_of_mcc_of_imsi_array.get_data_length())); |
|
455 |
|
456 u32_t count = m_2_digit_mnc_map_of_mcc_of_imsi_array.get_data_length() / sizeof(u32_t); |
|
457 |
|
458 for (u32_t ind = 0ul; ind < count; ind++) |
|
459 { |
|
460 if (mcc == mcc_array[ind]) |
|
461 { |
|
462 return EAP_TYPE_GSMSIM_MNC_LENGTH_2_BYTES; |
|
463 } |
|
464 } |
|
465 |
|
466 return EAP_TYPE_GSMSIM_DEFAULT_MNC_LENGTH_3_BYTES; |
|
467 } |
|
468 |
|
469 //-------------------------------------------------- |
|
470 |
|
471 eap_status_e eap_type_gsmsim_c::create_uma_realm( |
|
472 eap_variable_data_c * const automatic_realm, |
|
473 const eap_variable_data_c * const IMSI, |
|
474 const u32_t length_of_mnc) |
|
475 { |
|
476 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
477 |
|
478 eap_status_e status(eap_status_ok); |
|
479 |
|
480 // Create special automatic realm for UMA. |
|
481 automatic_realm->reset(); |
|
482 |
|
483 if (m_use_uma_profile == true) |
|
484 { |
|
485 // Create special automatic realm for UMA. |
|
486 automatic_realm->reset(); |
|
487 |
|
488 if (m_uma_automatic_realm_prefix.get_is_valid_data() == true) |
|
489 { |
|
490 status = automatic_realm->add_data(&m_uma_automatic_realm_prefix); |
|
491 } |
|
492 |
|
493 if (status != eap_status_ok) |
|
494 { |
|
495 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
496 return EAP_STATUS_RETURN(m_am_tools, status); |
|
497 } |
|
498 |
|
499 if (automatic_realm->get_data_length() > 0ul) |
|
500 { |
|
501 status = automatic_realm->add_data(GSMSIM_OWLAN_DOT_STRING, GSMSIM_OWLAN_DOT_STRING_LENGTH); |
|
502 if (status != eap_status_ok) |
|
503 { |
|
504 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
505 return EAP_STATUS_RETURN(m_am_tools, status); |
|
506 } |
|
507 } |
|
508 |
|
509 status = automatic_realm->add_data(GSMSIM_OWLAN_MNC_STRING, GSMSIM_OWLAN_MNC_STRING_LENGTH); |
|
510 if (status != eap_status_ok) |
|
511 { |
|
512 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
513 return EAP_STATUS_RETURN(m_am_tools, status); |
|
514 } |
|
515 |
|
516 // MNC part. |
|
517 if (length_of_mnc == EAP_TYPE_GSMSIM_MNC_LENGTH_2_BYTES) |
|
518 { |
|
519 // Add zero digit. |
|
520 u8_t zero = '0'; |
|
521 status = automatic_realm->add_data(&zero, sizeof(zero)); |
|
522 if (status != eap_status_ok) |
|
523 { |
|
524 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
525 return EAP_STATUS_RETURN(m_am_tools, status); |
|
526 } |
|
527 } |
|
528 status = automatic_realm->add_data(IMSI->get_data_offset(EAP_TYPE_GSMSIM_MNC_OFFSET, length_of_mnc), length_of_mnc); |
|
529 if (status != eap_status_ok) |
|
530 { |
|
531 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
532 return EAP_STATUS_RETURN(m_am_tools, status); |
|
533 } |
|
534 |
|
535 status = automatic_realm->add_data(GSMSIM_OWLAN_DOT_STRING, GSMSIM_OWLAN_DOT_STRING_LENGTH); |
|
536 if (status != eap_status_ok) |
|
537 { |
|
538 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
539 return EAP_STATUS_RETURN(m_am_tools, status); |
|
540 } |
|
541 |
|
542 status = automatic_realm->add_data(GSMSIM_OWLAN_MCC_STRING, GSMSIM_OWLAN_MCC_STRING_LENGTH); |
|
543 if (status != eap_status_ok) |
|
544 { |
|
545 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
546 return EAP_STATUS_RETURN(m_am_tools, status); |
|
547 } |
|
548 |
|
549 // MCC part is in index 0 and it is 3 bytes long. |
|
550 status = automatic_realm->add_data(IMSI->get_data_offset(EAP_TYPE_GSMSIM_MCC_OFFSET, EAP_TYPE_GSMSIM_MCC_LENGTH), EAP_TYPE_GSMSIM_MCC_LENGTH); |
|
551 if (status != eap_status_ok) |
|
552 { |
|
553 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
554 return EAP_STATUS_RETURN(m_am_tools, status); |
|
555 } |
|
556 |
|
557 status = automatic_realm->add_data(GSMSIM_OWLAN_DOT_STRING, GSMSIM_OWLAN_DOT_STRING_LENGTH); |
|
558 if (status != eap_status_ok) |
|
559 { |
|
560 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
561 return EAP_STATUS_RETURN(m_am_tools, status); |
|
562 } |
|
563 |
|
564 status = automatic_realm->add_data(GSMSIM_OWLAN_ORG_STRING, GSMSIM_OWLAN_ORG_STRING_LENGTH); |
|
565 if (status != eap_status_ok) |
|
566 { |
|
567 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
568 return EAP_STATUS_RETURN(m_am_tools, status); |
|
569 } |
|
570 } |
|
571 |
|
572 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
573 return EAP_STATUS_RETURN(m_am_tools, status); |
|
574 } |
|
575 |
|
576 //-------------------------------------------------- |
|
577 |
|
578 // |
|
579 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query( |
|
580 const eap_variable_data_c * const IMSI, |
|
581 const eap_variable_data_c * const p_pseudonym_identity, |
|
582 const eap_variable_data_c * const p_reauthentication_identity, |
|
583 const eap_variable_data_c * const p_automatic_realm, ///< This could be zero pointer if this is not used. |
|
584 const u32_t length_of_mnc, |
|
585 const eap_type_gsmsim_complete_e required_completion, |
|
586 const u8_t received_eap_identifier, |
|
587 const eap_status_e completion_status |
|
588 ) |
|
589 { |
|
590 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
591 |
|
592 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
593 |
|
594 eap_status_e status = eap_status_process_general_error; |
|
595 |
|
596 if (completion_status != eap_status_ok |
|
597 || IMSI == 0 |
|
598 || p_pseudonym_identity == 0 |
|
599 || p_reauthentication_identity == 0) |
|
600 { |
|
601 set_state(eap_type_gsmsim_state_failure); |
|
602 |
|
603 // The eap_status_process_general_error error value is more important |
|
604 // than return value of set_session_timeout(). |
|
605 get_type_partner()->set_session_timeout(0ul); |
|
606 |
|
607 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); |
|
608 } |
|
609 |
|
610 |
|
611 const eap_variable_data_c * local_pseudonym_identity = p_pseudonym_identity; |
|
612 const eap_variable_data_c * local_reauthentication_identity = p_reauthentication_identity; |
|
613 |
|
614 if (m_use_pseudonym_identity == false) |
|
615 { |
|
616 // We do not want use pseudonym identity. |
|
617 local_pseudonym_identity = 0; |
|
618 } |
|
619 |
|
620 if (m_use_reauthentication_identity == false) |
|
621 { |
|
622 // We do not want use re-authentication identity. |
|
623 local_reauthentication_identity = 0; |
|
624 } |
|
625 |
|
626 if (m_state != eap_type_gsmsim_state_pending_identity_query) |
|
627 { |
|
628 // Authentication is terminated or state is wrong. Cannot continue. |
|
629 set_state(eap_type_gsmsim_state_failure); |
|
630 |
|
631 // The eap_status_handler_does_not_exists_error error value is more important |
|
632 // than return value of set_session_timeout(). |
|
633 get_type_partner()->set_session_timeout(0ul); |
|
634 |
|
635 return EAP_STATUS_RETURN(m_am_tools, eap_status_handler_does_not_exists_error); |
|
636 } |
|
637 |
|
638 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
639 |
|
640 eap_variable_data_c local_automatic_realm(m_am_tools); |
|
641 |
|
642 if (p_automatic_realm == 0 |
|
643 || p_automatic_realm->get_is_valid_data() == false) |
|
644 { |
|
645 { |
|
646 // Here we read the length of the MNC. |
|
647 const u8_t * const MCC = IMSI->get_data_offset(EAP_TYPE_GSMSIM_MCC_OFFSET, EAP_TYPE_GSMSIM_MCC_LENGTH); |
|
648 if (MCC == 0) |
|
649 { |
|
650 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
651 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
652 } |
|
653 u32_t MCC_value(0ul); |
|
654 status = m_am_tools->number_string_to_u32( |
|
655 MCC, |
|
656 3ul, |
|
657 &MCC_value); |
|
658 if (status != eap_status_ok) |
|
659 { |
|
660 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
661 return EAP_STATUS_RETURN(m_am_tools, status); |
|
662 } |
|
663 m_length_of_mnc = get_mnc_length(MCC_value); |
|
664 } |
|
665 |
|
666 status = create_uma_realm(&local_automatic_realm, IMSI, m_length_of_mnc); |
|
667 if (status != eap_status_ok) |
|
668 { |
|
669 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
670 return EAP_STATUS_RETURN(m_am_tools, status); |
|
671 } |
|
672 |
|
673 if (local_automatic_realm.get_is_valid() == true) |
|
674 { |
|
675 status = m_automatic_realm.set_copy_of_buffer(&local_automatic_realm); |
|
676 if (status != eap_status_ok) |
|
677 { |
|
678 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
679 return EAP_STATUS_RETURN(m_am_tools, status); |
|
680 } |
|
681 } |
|
682 } |
|
683 else |
|
684 { |
|
685 status = local_automatic_realm.set_copy_of_buffer(p_automatic_realm); |
|
686 if (status != eap_status_ok) |
|
687 { |
|
688 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
689 return EAP_STATUS_RETURN(m_am_tools, status); |
|
690 } |
|
691 |
|
692 status = m_automatic_realm.set_copy_of_buffer(p_automatic_realm); |
|
693 if (status != eap_status_ok) |
|
694 { |
|
695 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
696 return EAP_STATUS_RETURN(m_am_tools, status); |
|
697 } |
|
698 |
|
699 m_length_of_mnc = length_of_mnc; |
|
700 |
|
701 } |
|
702 |
|
703 m_automatic_realm_read = true; |
|
704 |
|
705 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
706 |
|
707 if (required_completion == eap_type_gsmsim_complete_query_eap_identity) |
|
708 { |
|
709 status = handle_eap_identity_query( |
|
710 &m_send_network_id, |
|
711 0, |
|
712 m_last_eap_identifier, |
|
713 IMSI, |
|
714 local_pseudonym_identity, |
|
715 local_reauthentication_identity, |
|
716 &local_automatic_realm, |
|
717 m_length_of_mnc, |
|
718 false); |
|
719 if (status != eap_status_ok |
|
720 && status != eap_status_completed_request) |
|
721 { |
|
722 restore_saved_previous_state(); |
|
723 } |
|
724 } |
|
725 else if (required_completion == eap_type_gsmsim_complete_start_request) |
|
726 { |
|
727 if (local_reauthentication_identity != 0 |
|
728 && local_reauthentication_identity->get_is_valid_data() == true) |
|
729 { |
|
730 EAP_TRACE_DEBUG( |
|
731 m_am_tools, |
|
732 TRACE_FLAGS_DEFAULT, |
|
733 (EAPL("complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query reauthentication_identity\n"))); |
|
734 |
|
735 status = m_reauthentication_identity.set_copy_of_buffer(local_reauthentication_identity); |
|
736 if (status != eap_status_ok) |
|
737 { |
|
738 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
739 return EAP_STATUS_RETURN(m_am_tools, status); |
|
740 } |
|
741 |
|
742 status = store_identity(&m_reauthentication_identity, false); |
|
743 if (status != eap_status_ok) |
|
744 { |
|
745 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
746 return EAP_STATUS_RETURN(m_am_tools, status); |
|
747 } |
|
748 } |
|
749 else if (local_pseudonym_identity != 0 |
|
750 && local_pseudonym_identity->get_is_valid_data() == true) |
|
751 { |
|
752 EAP_TRACE_DEBUG( |
|
753 m_am_tools, |
|
754 TRACE_FLAGS_DEFAULT, |
|
755 (EAPL("complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query pseudonym\n"))); |
|
756 |
|
757 m_reauthentication_identity.reset(); |
|
758 status = m_pseudonym.set_copy_of_buffer(local_pseudonym_identity); |
|
759 if (status != eap_status_ok) |
|
760 { |
|
761 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
762 return EAP_STATUS_RETURN(m_am_tools, status); |
|
763 } |
|
764 |
|
765 status = store_identity(&m_pseudonym, false); |
|
766 if (status != eap_status_ok) |
|
767 { |
|
768 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
769 return EAP_STATUS_RETURN(m_am_tools, status); |
|
770 } |
|
771 } |
|
772 else if (IMSI->get_is_valid_data() == true |
|
773 && IMSI->get_data_length() >= EAP_TYPE_GSMSIM_MINIMUM_IMSI_LENGTH) |
|
774 { |
|
775 EAP_TRACE_DEBUG( |
|
776 m_am_tools, |
|
777 TRACE_FLAGS_DEFAULT, |
|
778 (EAPL("complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query IMSI\n"))); |
|
779 |
|
780 m_reauthentication_identity.reset(); |
|
781 m_pseudonym.reset(); |
|
782 status = m_IMSI.set_copy_of_buffer(IMSI); |
|
783 if (status != eap_status_ok) |
|
784 { |
|
785 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
786 return EAP_STATUS_RETURN(m_am_tools, status); |
|
787 } |
|
788 |
|
789 status = store_identity(&m_IMSI, true); |
|
790 if (status != eap_status_ok) |
|
791 { |
|
792 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
793 return EAP_STATUS_RETURN(m_am_tools, status); |
|
794 } |
|
795 } |
|
796 |
|
797 save_current_state(); |
|
798 set_state(eap_type_gsmsim_state_analyse_start_request); |
|
799 |
|
800 EAP_TRACE_DEBUG( |
|
801 m_am_tools, |
|
802 TRACE_FLAGS_DEFAULT, |
|
803 (EAPL("complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query(0x%08x).\n"), |
|
804 this)); |
|
805 |
|
806 // Here we swap the addresses. |
|
807 eap_am_network_id_c receive_network_id(m_am_tools, |
|
808 m_send_network_id.get_destination_id(), |
|
809 m_send_network_id.get_source_id(), |
|
810 m_send_network_id.get_type()); |
|
811 |
|
812 status = send_start_response_message( |
|
813 &receive_network_id, |
|
814 received_eap_identifier, |
|
815 m_gsmsim_selected_version, |
|
816 m_include_identity_to_start_response, |
|
817 &local_automatic_realm, |
|
818 m_length_of_mnc); |
|
819 |
|
820 if (status == eap_status_ok) |
|
821 { |
|
822 } |
|
823 else |
|
824 { |
|
825 restore_saved_previous_state(); |
|
826 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
827 return EAP_STATUS_RETURN(m_am_tools, status); |
|
828 } |
|
829 } |
|
830 |
|
831 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
832 return EAP_STATUS_RETURN(m_am_tools, status); |
|
833 } |
|
834 |
|
835 //-------------------------------------------------- |
|
836 |
|
837 // |
|
838 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::complete_SIM_kc_sres( |
|
839 const eap_variable_data_c * const n_rand, |
|
840 const eap_variable_data_c * const n_kc, |
|
841 const eap_variable_data_c * const n_sres, |
|
842 const eap_status_e completion_status) |
|
843 { |
|
844 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
845 |
|
846 EAP_ASSERT(m_am_tools->get_global_mutex()->get_is_reserved() == true); |
|
847 |
|
848 eap_status_e status = eap_status_process_general_error; |
|
849 |
|
850 if (completion_status != eap_status_ok |
|
851 || n_rand == 0 |
|
852 || n_kc == 0 |
|
853 || n_sres == 0) |
|
854 { |
|
855 if (completion_status == eap_status_not_fresh_challenges) |
|
856 { |
|
857 (void) initialize_error_message(completion_status); |
|
858 |
|
859 restore_saved_previous_state(); |
|
860 } |
|
861 else |
|
862 { |
|
863 set_state(eap_type_gsmsim_state_failure); |
|
864 |
|
865 // The eap_status_process_general_error error value is more important |
|
866 // than return value of set_session_timeout(). |
|
867 get_type_partner()->set_session_timeout(0ul); |
|
868 } |
|
869 |
|
870 return EAP_STATUS_RETURN(m_am_tools, completion_status); |
|
871 } |
|
872 |
|
873 |
|
874 if (m_state != eap_type_gsmsim_state_pending_kc_sres_query) |
|
875 { |
|
876 // Authentication is terminated or state is wrong. Cannot continue. |
|
877 set_state(eap_type_gsmsim_state_failure); |
|
878 |
|
879 // The eap_status_handler_does_not_exists_error error value is more important |
|
880 // than return value of set_session_timeout(). |
|
881 get_type_partner()->set_session_timeout(0ul); |
|
882 |
|
883 return EAP_STATUS_RETURN(m_am_tools, eap_status_handler_does_not_exists_error); |
|
884 } |
|
885 |
|
886 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
887 |
|
888 status = process_SIM_kc_sres( |
|
889 n_rand, |
|
890 n_kc, |
|
891 n_sres); |
|
892 |
|
893 if (status != eap_status_ok |
|
894 && status != eap_status_success) |
|
895 { |
|
896 (void) initialize_error_message(status); |
|
897 |
|
898 restore_saved_previous_state(); |
|
899 } |
|
900 |
|
901 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
902 return EAP_STATUS_RETURN(m_am_tools, status); |
|
903 } |
|
904 |
|
905 //-------------------------------------------------- |
|
906 |
|
907 // |
|
908 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::process_SIM_kc_sres( |
|
909 const eap_variable_data_c * const n_rand, |
|
910 const eap_variable_data_c * const n_kc, |
|
911 const eap_variable_data_c * const n_sres) |
|
912 { |
|
913 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
914 |
|
915 eap_status_e status = eap_status_process_general_error; |
|
916 |
|
917 eap_variable_data_c MAC_RAND(m_am_tools); |
|
918 |
|
919 if (m_state != eap_type_gsmsim_state_pending_kc_sres_query |
|
920 || n_rand == 0 |
|
921 || n_kc == 0 |
|
922 || n_sres == 0) |
|
923 { |
|
924 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); |
|
925 } |
|
926 |
|
927 if (m_identity.get_is_valid_data() == false) |
|
928 { |
|
929 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); |
|
930 } |
|
931 |
|
932 if (m_nonce_mt.get_is_valid_data() == false) |
|
933 { |
|
934 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
935 } |
|
936 |
|
937 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
938 |
|
939 EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, (EAPL("n*RAND"), |
|
940 n_rand->get_data(), |
|
941 n_rand->get_data_length())); |
|
942 EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("n*KC"), |
|
943 n_kc->get_data(), |
|
944 n_kc->get_data_length())); |
|
945 EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("n*SRES"), |
|
946 n_sres->get_data(), |
|
947 n_sres->get_data_length())); |
|
948 EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("identity"), |
|
949 m_identity.get_data(), |
|
950 m_identity.get_data_length())); |
|
951 EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("NONCE MT"), |
|
952 m_nonce_mt.get_data(), |
|
953 m_nonce_mt.get_data_length())); |
|
954 |
|
955 |
|
956 status = m_n_sres.set_copy_of_buffer(n_sres); |
|
957 if (status != eap_status_ok) |
|
958 { |
|
959 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
960 return EAP_STATUS_RETURN(m_am_tools, status); |
|
961 } |
|
962 |
|
963 eap_variable_data_c XKEY(m_am_tools); |
|
964 eap_variable_data_c K_encr(m_am_tools); |
|
965 eap_variable_data_c K_aut(m_am_tools); |
|
966 eap_variable_data_c master_session_key(m_am_tools); |
|
967 |
|
968 status = generate_shared_secred_keys( |
|
969 EAP_TYPE_GSMSIM_KEYMAT_SIZE, |
|
970 n_kc, |
|
971 n_sres, |
|
972 &XKEY, |
|
973 &K_encr, |
|
974 &K_aut, |
|
975 &master_session_key); |
|
976 if (status != eap_status_ok) |
|
977 { |
|
978 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
979 return EAP_STATUS_RETURN(m_am_tools, status); |
|
980 } |
|
981 |
|
982 if (m_saved_EAP_packet.get_is_valid_data() == true) |
|
983 { |
|
984 gsmsim_payloads_c * const l_gsmsim_payloads = new gsmsim_payloads_c(m_am_tools); |
|
985 eap_automatic_variable_c<gsmsim_payloads_c> l_gsmsim_payloads_automatic(m_am_tools, l_gsmsim_payloads); |
|
986 |
|
987 if (l_gsmsim_payloads == 0 |
|
988 || l_gsmsim_payloads->get_is_valid() == false) |
|
989 { |
|
990 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
991 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
992 } |
|
993 |
|
994 gsmsim_header_c saved_EAP_packet( |
|
995 m_am_tools, |
|
996 m_saved_EAP_packet.get_data(), |
|
997 m_saved_EAP_packet.get_data_length()); |
|
998 |
|
999 if (saved_EAP_packet.get_is_valid() == false) |
|
1000 { |
|
1001 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1002 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
1003 } |
|
1004 |
|
1005 status = parse_gsmsim_packet( |
|
1006 &saved_EAP_packet, |
|
1007 m_saved_EAP_packet.get_data_length(), |
|
1008 l_gsmsim_payloads); |
|
1009 if (status != eap_status_ok) |
|
1010 { |
|
1011 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1012 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1013 } |
|
1014 |
|
1015 status = check_message_authentication_code( |
|
1016 &K_aut, |
|
1017 l_gsmsim_payloads, |
|
1018 &saved_EAP_packet, |
|
1019 saved_EAP_packet.get_length()); |
|
1020 if (status != eap_status_ok) |
|
1021 { |
|
1022 (void) initialize_error_message(status); |
|
1023 |
|
1024 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1025 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1026 } |
|
1027 |
|
1028 // Decrypt and parse encrypted payload. |
|
1029 if (l_gsmsim_payloads->get_IV()->get_payload_included() == true |
|
1030 || l_gsmsim_payloads->get_ENCR_DATA()->get_payload_included() == true) |
|
1031 { |
|
1032 if (l_gsmsim_payloads->get_IV()->get_payload_included() == true |
|
1033 && l_gsmsim_payloads->get_ENCR_DATA()->get_payload_included() == true |
|
1034 && l_gsmsim_payloads->get_MAC()->get_payload_included() == true) |
|
1035 { |
|
1036 status = decrypt_DATA_payload( |
|
1037 l_gsmsim_payloads, |
|
1038 &K_encr); |
|
1039 if (status != eap_status_ok) |
|
1040 { |
|
1041 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1042 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1043 } |
|
1044 |
|
1045 status = handle_DATA_payload( |
|
1046 gsmsim_subtype_Challenge, |
|
1047 l_gsmsim_payloads); |
|
1048 if (status != eap_status_ok) |
|
1049 { |
|
1050 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1051 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1052 } |
|
1053 } |
|
1054 else |
|
1055 { |
|
1056 // All of these must be included |
|
1057 // or none of these must be included. |
|
1058 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1059 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); |
|
1060 } |
|
1061 } |
|
1062 else |
|
1063 { |
|
1064 // No encrypted payload. |
|
1065 // GSMSIM AM should remove re-authentication identity from favourite place. |
|
1066 |
|
1067 EAP_TRACE_DEBUG( |
|
1068 m_am_tools, |
|
1069 TRACE_FLAGS_DEFAULT, |
|
1070 (EAPL("eap_type_gsmsim_c::process_SIM_kc_sres(0x%08x): Resets re-authentication identity from database.\n"), |
|
1071 this)); |
|
1072 |
|
1073 status = m_am_type_gsmsim->store_reauthentication_id( |
|
1074 &m_send_network_id, |
|
1075 0); |
|
1076 if (status != eap_status_ok) |
|
1077 { |
|
1078 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1079 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1080 } |
|
1081 |
|
1082 m_reauthentication_identity.reset(); |
|
1083 } |
|
1084 } |
|
1085 else |
|
1086 { |
|
1087 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1088 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); |
|
1089 } |
|
1090 |
|
1091 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
1092 |
|
1093 status = send_challenge_response_message( |
|
1094 &K_aut); |
|
1095 if (status != eap_status_ok) |
|
1096 { |
|
1097 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1098 } |
|
1099 |
|
1100 // Store keys. |
|
1101 status = m_XKEY.set_copy_of_buffer(&XKEY); |
|
1102 if (status != eap_status_ok) |
|
1103 { |
|
1104 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1105 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1106 } |
|
1107 status = m_K_encr.set_copy_of_buffer(&K_encr); |
|
1108 if (status != eap_status_ok) |
|
1109 { |
|
1110 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1111 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1112 } |
|
1113 status = m_K_aut.set_copy_of_buffer(&K_aut); |
|
1114 if (status != eap_status_ok) |
|
1115 { |
|
1116 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1117 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1118 } |
|
1119 status = m_master_session_key.set_copy_of_buffer(&master_session_key); |
|
1120 if (status != eap_status_ok) |
|
1121 { |
|
1122 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1123 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1124 } |
|
1125 |
|
1126 // In order to use re-authentication, the client and the server need to |
|
1127 // store the following values: original XKEY, K_aut, K_encr, latest |
|
1128 // counter value and the next re-authentication identity. |
|
1129 status = m_am_type_gsmsim->store_reauth_parameters( |
|
1130 &XKEY, |
|
1131 &K_aut, |
|
1132 &K_encr, |
|
1133 EAP_TYPE_GSMSIM_INITIAL_REAUTH_COUNTER); |
|
1134 if (status != eap_status_ok) |
|
1135 { |
|
1136 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1137 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1138 } |
|
1139 |
|
1140 // Authentication was successful. |
|
1141 if (m_use_result_indication == true) |
|
1142 { |
|
1143 // This version waits result indication. |
|
1144 if (m_authentication_type == GSMSIM_AUTHENTICATION_TYPE_REAUTHENTICATION) |
|
1145 { |
|
1146 EAP_TRACE_DEBUG( |
|
1147 m_am_tools, |
|
1148 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
1149 (EAPL("EAP_type_GSMSIM: %s, re-authentication OK, waits result indication\n"), |
|
1150 (m_is_client == true) ? "client": "server")); |
|
1151 } |
|
1152 else if (m_authentication_type == GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH) |
|
1153 { |
|
1154 if (m_identity_type == GSMSIM_IDENTITY_TYPE_PSEUDONYM_ID) |
|
1155 { |
|
1156 EAP_TRACE_DEBUG( |
|
1157 m_am_tools, |
|
1158 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
1159 (EAPL("EAP_type_GSMSIM: %s, full authentication OK, pseudonym identity, waits result indication\n"), |
|
1160 (m_is_client == true) ? "client": "server")); |
|
1161 } |
|
1162 else if (m_identity_type == GSMSIM_IDENTITY_TYPE_IMSI_ID) |
|
1163 { |
|
1164 EAP_TRACE_DEBUG( |
|
1165 m_am_tools, |
|
1166 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
1167 (EAPL("EAP_type_GSMSIM: %s, full authentication OK, IMSI identity, waits result indication\n"), |
|
1168 (m_is_client == true) ? "client": "server")); |
|
1169 } |
|
1170 else if (m_identity_type == GSMSIM_IDENTITY_TYPE_RE_AUTH_ID) |
|
1171 { |
|
1172 EAP_TRACE_DEBUG( |
|
1173 m_am_tools, |
|
1174 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
1175 (EAPL("EAP_type_GSMSIM: %s, full authentication OK, Re-auth identity, waits result indication\n"), |
|
1176 (m_is_client == true) ? "client": "server")); |
|
1177 } |
|
1178 else |
|
1179 { |
|
1180 EAP_TRACE_ERROR( |
|
1181 m_am_tools, |
|
1182 TRACE_FLAGS_GSMSIM_ERROR|TRACE_TEST_VECTORS, |
|
1183 (EAPL("ERROR: EAP_type_GSMSIM: %s, full authentication OK, unknown identity\n"), |
|
1184 (m_is_client == true) ? "client": "server")); |
|
1185 |
|
1186 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1187 return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); |
|
1188 } |
|
1189 } |
|
1190 else |
|
1191 { |
|
1192 EAP_TRACE_ERROR( |
|
1193 m_am_tools, |
|
1194 TRACE_FLAGS_GSMSIM_ERROR|TRACE_TEST_VECTORS, |
|
1195 (EAPL("ERROR: EAP_type_GSMSIM: %s, unknown authentication OK, unknown identity\n"), |
|
1196 (m_is_client == true) ? "client": "server")); |
|
1197 |
|
1198 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1199 return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); |
|
1200 } |
|
1201 |
|
1202 set_state(eap_type_gsmsim_state_waiting_for_notification_request_success); |
|
1203 } |
|
1204 else if (m_wait_eap_success_packet == false) |
|
1205 { |
|
1206 // This version does not wait EAP-Success message. |
|
1207 if (m_send_network_id.get_is_valid_data() == false) |
|
1208 { |
|
1209 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1210 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); |
|
1211 } |
|
1212 |
|
1213 // Here we swap the addresses. |
|
1214 eap_am_network_id_c receive_network_id(m_am_tools, |
|
1215 m_send_network_id.get_destination_id(), |
|
1216 m_send_network_id.get_source_id(), |
|
1217 m_send_network_id.get_type()); |
|
1218 |
|
1219 // This version does not wait EAP-Success message. |
|
1220 status = finish_successful_authentication( |
|
1221 &receive_network_id); |
|
1222 if (status != eap_status_ok) |
|
1223 { |
|
1224 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1225 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1226 } |
|
1227 } |
|
1228 else |
|
1229 { |
|
1230 // This version waits the EAP-Success message. |
|
1231 |
|
1232 if (m_authentication_type == GSMSIM_AUTHENTICATION_TYPE_REAUTHENTICATION) |
|
1233 { |
|
1234 EAP_TRACE_DEBUG( |
|
1235 m_am_tools, |
|
1236 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
1237 (EAPL("EAP_type_GSMSIM: %s, re-authentication OK, waits EAP-Success\n"), |
|
1238 (m_is_client == true) ? "client": "server")); |
|
1239 } |
|
1240 else if (m_authentication_type == GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH) |
|
1241 { |
|
1242 if (m_identity_type == GSMSIM_IDENTITY_TYPE_PSEUDONYM_ID) |
|
1243 { |
|
1244 EAP_TRACE_DEBUG( |
|
1245 m_am_tools, |
|
1246 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
1247 (EAPL("EAP_type_GSMSIM: %s, full authentication OK, pseudonym identity, waits EAP-Success\n"), |
|
1248 (m_is_client == true) ? "client": "server")); |
|
1249 } |
|
1250 else if (m_identity_type == GSMSIM_IDENTITY_TYPE_IMSI_ID) |
|
1251 { |
|
1252 EAP_TRACE_DEBUG( |
|
1253 m_am_tools, |
|
1254 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
1255 (EAPL("EAP_type_GSMSIM: %s, full authentication OK, IMSI identity, waits EAP-Success\n"), |
|
1256 (m_is_client == true) ? "client": "server")); |
|
1257 } |
|
1258 else if (m_identity_type == GSMSIM_IDENTITY_TYPE_RE_AUTH_ID) |
|
1259 { |
|
1260 EAP_TRACE_DEBUG( |
|
1261 m_am_tools, |
|
1262 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
1263 (EAPL("EAP_type_GSMSIM: %s, full authentication OK, Re-auth identity, waits EAP-Success\n"), |
|
1264 (m_is_client == true) ? "client": "server")); |
|
1265 } |
|
1266 else |
|
1267 { |
|
1268 EAP_TRACE_ERROR( |
|
1269 m_am_tools, |
|
1270 TRACE_FLAGS_GSMSIM_ERROR|TRACE_TEST_VECTORS, |
|
1271 (EAPL("ERROR: EAP_type_GSMSIM: %s, full authentication OK, unknown identity, waits EAP-Success\n"), |
|
1272 (m_is_client == true) ? "client": "server")); |
|
1273 |
|
1274 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1275 return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); |
|
1276 } |
|
1277 } |
|
1278 else |
|
1279 { |
|
1280 EAP_TRACE_ERROR( |
|
1281 m_am_tools, |
|
1282 TRACE_FLAGS_GSMSIM_ERROR|TRACE_TEST_VECTORS, |
|
1283 (EAPL("ERROR: EAP_type_GSMSIM: %s, unknown authentication OK, unknown identity, waits EAP-Success\n"), |
|
1284 (m_is_client == true) ? "client": "server")); |
|
1285 |
|
1286 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1287 return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); |
|
1288 } |
|
1289 |
|
1290 set_state(eap_type_gsmsim_state_waiting_for_success); |
|
1291 status = eap_status_ok; |
|
1292 } |
|
1293 |
|
1294 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1295 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1296 } |
|
1297 |
|
1298 //-------------------------------------------------- |
|
1299 |
|
1300 // |
|
1301 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::send_start_response_message( |
|
1302 const eap_am_network_id_c * const receive_network_id, |
|
1303 const u8_t received_eap_identifier, |
|
1304 const eap_gsmsim_version version, |
|
1305 const gsmsim_payload_AT_type_e include_identity_to_start_response, |
|
1306 const eap_variable_data_c * const automatic_realm, ///< This could be zero pointer if this is not used. |
|
1307 const u32_t /* length_of_mnc */ |
|
1308 ) |
|
1309 { |
|
1310 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1311 |
|
1312 EAP_TRACE_DEBUG( |
|
1313 m_am_tools, |
|
1314 TRACE_FLAGS_DEFAULT, |
|
1315 (EAPL(" send: GSMSIM-type %10s, %s, state %2d=%s\n"), |
|
1316 EAPL("gsmsim_subtype_Start"), |
|
1317 (m_is_client) ? EAPL("client") : EAPL("server"), |
|
1318 m_state, |
|
1319 get_state_string() |
|
1320 )); |
|
1321 |
|
1322 eap_buf_chain_wr_c gsmsim_initial_reply( |
|
1323 eap_write_buffer, |
|
1324 m_am_tools, |
|
1325 EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); |
|
1326 |
|
1327 if (gsmsim_initial_reply.get_is_valid() == false) |
|
1328 { |
|
1329 EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n"))); |
|
1330 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1331 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1332 } |
|
1333 |
|
1334 #if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) |
|
1335 if (m_is_client == true |
|
1336 && m_client_responds_retransmitted_packets == true) |
|
1337 { |
|
1338 // We do not wan't lower layers do re-transmissions behalf of us. |
|
1339 // This means GSMSIM does process every re-transmitted EAP-Request. |
|
1340 gsmsim_initial_reply.set_do_packet_retransmission(false); |
|
1341 } |
|
1342 #endif //#if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) |
|
1343 |
|
1344 EAP_ASSERT_ALWAYS(EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH >= (m_gsmsim_header_offset+m_trailer_length)); |
|
1345 u32_t packet_buffer_free = EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length; |
|
1346 u32_t packet_buffer_offset = 0u; |
|
1347 |
|
1348 if (m_gsmsim_header_offset+m_MTU < packet_buffer_free) |
|
1349 { |
|
1350 packet_buffer_free = m_gsmsim_header_offset+m_MTU; |
|
1351 } |
|
1352 |
|
1353 gsmsim_header_c gsmsim_response( |
|
1354 m_am_tools, |
|
1355 gsmsim_initial_reply.get_data_offset( |
|
1356 m_gsmsim_header_offset, |
|
1357 (packet_buffer_free-m_gsmsim_header_offset)), |
|
1358 (packet_buffer_free-m_gsmsim_header_offset)); |
|
1359 |
|
1360 if (gsmsim_response.get_is_valid() == false) |
|
1361 { |
|
1362 EAP_TRACE_ERROR( |
|
1363 m_am_tools, |
|
1364 TRACE_FLAGS_DEFAULT, |
|
1365 (EAPL("packet_send: packet buffer corrupted.\n"))); |
|
1366 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
1367 } |
|
1368 |
|
1369 // Here we swap the addresses. |
|
1370 eap_am_network_id_c send_network_id(m_am_tools, |
|
1371 receive_network_id->get_destination_id(), |
|
1372 receive_network_id->get_source_id(), |
|
1373 receive_network_id->get_type()); |
|
1374 |
|
1375 gsmsim_response.reset_header( |
|
1376 packet_buffer_free-m_gsmsim_header_offset, |
|
1377 m_use_eap_expanded_type); |
|
1378 gsmsim_response.set_length( |
|
1379 static_cast<u16_t>(packet_buffer_free-m_gsmsim_header_offset), |
|
1380 m_use_eap_expanded_type); |
|
1381 gsmsim_response.set_code(eap_code_response); |
|
1382 gsmsim_response.set_identifier(received_eap_identifier); |
|
1383 gsmsim_response.set_type( |
|
1384 eap_type_gsmsim, |
|
1385 m_use_eap_expanded_type); |
|
1386 |
|
1387 gsmsim_response.set_subtype(gsmsim_subtype_Start); |
|
1388 |
|
1389 EAP_TRACE_DEBUG( |
|
1390 m_am_tools, |
|
1391 TRACE_FLAGS_DEFAULT, |
|
1392 (EAPL("eap_type_gsmsim_c::send_start_response_message(0x%08x): include_identity_to_start_response %d=%s.\n"), |
|
1393 this, |
|
1394 include_identity_to_start_response, |
|
1395 gsmsim_payload_AT_header_c::get_payload_AT_string(include_identity_to_start_response))); |
|
1396 |
|
1397 update_buffer_indexes( |
|
1398 EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, |
|
1399 m_gsmsim_header_offset+gsmsim_response.get_header_length(), |
|
1400 &packet_buffer_offset, |
|
1401 &packet_buffer_free); |
|
1402 |
|
1403 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
1404 |
|
1405 u32_t gsmsim_data_free = packet_buffer_free; |
|
1406 u32_t gsmsim_data_offset = 0u; |
|
1407 eap_status_e status = eap_status_process_general_error; |
|
1408 |
|
1409 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
1410 |
|
1411 if (m_identity_type == GSMSIM_IDENTITY_TYPE_RE_AUTH_ID) |
|
1412 { |
|
1413 // Re-authentication identity MUST be removed after first use. |
|
1414 // GSMSIM AM should remove re-authentication identity from favourite place. |
|
1415 |
|
1416 EAP_TRACE_DEBUG( |
|
1417 m_am_tools, |
|
1418 TRACE_FLAGS_DEFAULT, |
|
1419 (EAPL("eap_type_gsmsim_c::send_start_response_message(0x%08x): Resets re-authentication identity from database.\n"), |
|
1420 this)); |
|
1421 |
|
1422 status = m_am_type_gsmsim->store_reauthentication_id( |
|
1423 &m_send_network_id, |
|
1424 0); |
|
1425 if (status != eap_status_ok) |
|
1426 { |
|
1427 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1428 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1429 } |
|
1430 |
|
1431 // Do not reset the local copy of re-authentocation identity. |
|
1432 } |
|
1433 |
|
1434 if (include_identity_to_start_response == gsmsim_payload_AT_PERMANENT_ID_REQ) |
|
1435 { |
|
1436 m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH; |
|
1437 set_identity_type(GSMSIM_IDENTITY_TYPE_IMSI_ID); |
|
1438 |
|
1439 EAP_TRACE_DEBUG( |
|
1440 m_am_tools, |
|
1441 TRACE_FLAGS_DEFAULT, |
|
1442 (EAPL("eap_type_gsmsim_c::send_start_response_message(0x%08x): Selects full authentication and IMSI identity.\n"), |
|
1443 this)); |
|
1444 } |
|
1445 else if (include_identity_to_start_response == gsmsim_payload_AT_FULLAUTH_ID_REQ) |
|
1446 { |
|
1447 eap_variable_data_c * const pseudonym = &m_pseudonym; |
|
1448 |
|
1449 if (pseudonym->get_is_valid_data() == true) |
|
1450 { |
|
1451 // We have pseudonym. |
|
1452 m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH; |
|
1453 set_identity_type(GSMSIM_IDENTITY_TYPE_PSEUDONYM_ID); |
|
1454 |
|
1455 EAP_TRACE_DEBUG( |
|
1456 m_am_tools, |
|
1457 TRACE_FLAGS_DEFAULT, |
|
1458 (EAPL("eap_type_gsmsim_c::send_start_response_message(0x%08x): Selects full authentication and pseudonym identity.\n"), |
|
1459 this)); |
|
1460 } |
|
1461 else // if (pseudonym->get_is_valid() == false) |
|
1462 { |
|
1463 // Because no pseudonym is available we must use IMSI. |
|
1464 m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH; |
|
1465 set_identity_type(GSMSIM_IDENTITY_TYPE_IMSI_ID); |
|
1466 |
|
1467 EAP_TRACE_DEBUG( |
|
1468 m_am_tools, |
|
1469 TRACE_FLAGS_DEFAULT, |
|
1470 (EAPL("eap_type_gsmsim_c::send_start_response_message(0x%08x): Selects full authentication and IMSI identity.\n"), |
|
1471 this)); |
|
1472 } |
|
1473 } |
|
1474 else if (include_identity_to_start_response == gsmsim_payload_AT_ANY_ID_REQ) |
|
1475 { |
|
1476 eap_variable_data_c * const reauthentication_identity = &m_reauthentication_identity; |
|
1477 eap_variable_data_c * const pseudonym = &m_pseudonym; |
|
1478 |
|
1479 if (reauthentication_identity->get_is_valid_data() == true) |
|
1480 { |
|
1481 // We have reauthentication identity. Re-authentication identity is NAI. |
|
1482 m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_REAUTHENTICATION; |
|
1483 set_identity_type(GSMSIM_IDENTITY_TYPE_RE_AUTH_ID); |
|
1484 |
|
1485 EAP_TRACE_DEBUG( |
|
1486 m_am_tools, |
|
1487 TRACE_FLAGS_DEFAULT, |
|
1488 (EAPL("eap_type_gsmsim_c::send_start_response_message(0x%08x): Selects fast re-authentication and re-authentication identity.\n"), |
|
1489 this)); |
|
1490 } |
|
1491 else if (pseudonym->get_is_valid_data() == true) |
|
1492 { |
|
1493 // We have pseudonym. |
|
1494 m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH; |
|
1495 set_identity_type(GSMSIM_IDENTITY_TYPE_PSEUDONYM_ID); |
|
1496 |
|
1497 EAP_TRACE_DEBUG( |
|
1498 m_am_tools, |
|
1499 TRACE_FLAGS_DEFAULT, |
|
1500 (EAPL("eap_type_gsmsim_c::send_start_response_message(0x%08x): Selects full authentication and pseudonym identity.\n"), |
|
1501 this)); |
|
1502 } |
|
1503 else if (m_IMSI.get_is_valid_data() == true) |
|
1504 { |
|
1505 // Because no pseudonym is available we must use IMSI. |
|
1506 m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH; |
|
1507 set_identity_type(GSMSIM_IDENTITY_TYPE_IMSI_ID); |
|
1508 |
|
1509 EAP_TRACE_DEBUG( |
|
1510 m_am_tools, |
|
1511 TRACE_FLAGS_DEFAULT, |
|
1512 (EAPL("eap_type_gsmsim_c::send_start_response_message(0x%08x): Selects full authentication and IMSI identity.\n"), |
|
1513 this)); |
|
1514 } |
|
1515 else |
|
1516 { |
|
1517 // ERROR, no identity available. |
|
1518 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1519 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); |
|
1520 } |
|
1521 } |
|
1522 |
|
1523 if (m_authentication_type == GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH) |
|
1524 { |
|
1525 status = add_variable_payload( |
|
1526 &gsmsim_response, |
|
1527 EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, |
|
1528 gsmsim_response.get_header_length(), |
|
1529 &gsmsim_data_offset, |
|
1530 &gsmsim_data_free, |
|
1531 &packet_buffer_free, |
|
1532 &packet_buffer_offset, |
|
1533 &m_nonce_mt, |
|
1534 gsmsim_payload_AT_NONCE_MT); |
|
1535 if (status != eap_status_ok) |
|
1536 { |
|
1537 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1538 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1539 } |
|
1540 |
|
1541 status = add_version_payload( |
|
1542 &gsmsim_response, |
|
1543 EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, |
|
1544 gsmsim_response.get_header_length(), |
|
1545 &gsmsim_data_offset, |
|
1546 &gsmsim_data_free, |
|
1547 &packet_buffer_free, |
|
1548 &packet_buffer_offset, |
|
1549 version); |
|
1550 if (status != eap_status_ok) |
|
1551 { |
|
1552 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1553 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1554 } |
|
1555 } |
|
1556 |
|
1557 |
|
1558 if (include_identity_to_start_response != gsmsim_payload_NONE) |
|
1559 { |
|
1560 if (m_identity_type == GSMSIM_IDENTITY_TYPE_IMSI_ID) |
|
1561 { |
|
1562 eap_variable_data_c NAI(m_am_tools); |
|
1563 status = NAI.init(1u); |
|
1564 if (status != eap_status_ok) |
|
1565 { |
|
1566 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1567 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1568 } |
|
1569 NAI.set_is_valid(); |
|
1570 |
|
1571 status = generate_nai( |
|
1572 &NAI, |
|
1573 m_use_manual_realm, |
|
1574 get_nai_realm(), |
|
1575 &m_IMSI, |
|
1576 true, |
|
1577 &m_IMSI, |
|
1578 automatic_realm, |
|
1579 m_length_of_mnc); |
|
1580 if (status != eap_status_ok) |
|
1581 { |
|
1582 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1583 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1584 } |
|
1585 |
|
1586 status = add_pseudonym_or_imsi_payload( |
|
1587 &gsmsim_response, |
|
1588 EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, |
|
1589 gsmsim_response.get_header_length(), |
|
1590 &gsmsim_data_offset, |
|
1591 &gsmsim_data_free, |
|
1592 &packet_buffer_free, |
|
1593 &packet_buffer_offset, |
|
1594 &NAI, |
|
1595 gsmsim_payload_AT_IDENTITY); |
|
1596 if (status != eap_status_ok) |
|
1597 { |
|
1598 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1599 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1600 } |
|
1601 |
|
1602 // Save used NAI. |
|
1603 status = m_NAI.set_copy_of_buffer(&NAI); |
|
1604 if (status != eap_status_ok) |
|
1605 { |
|
1606 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1607 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1608 } |
|
1609 |
|
1610 EAP_TRACE_DEBUG( |
|
1611 m_am_tools, |
|
1612 TRACE_FLAGS_DEFAULT, |
|
1613 (EAPL("eap_type_gsmsim_c::send_start_response_message(): Client sends IMSI identity.\n"))); |
|
1614 } |
|
1615 else if (m_identity_type == GSMSIM_IDENTITY_TYPE_PSEUDONYM_ID) |
|
1616 { |
|
1617 eap_variable_data_c * const pseudonym = &m_pseudonym; |
|
1618 |
|
1619 if (pseudonym->get_is_valid_data() == true) |
|
1620 { |
|
1621 // We have pseudonym. |
|
1622 |
|
1623 eap_variable_data_c NAI(m_am_tools); |
|
1624 status = NAI.init(1u); |
|
1625 if (status != eap_status_ok) |
|
1626 { |
|
1627 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1628 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1629 } |
|
1630 NAI.set_is_valid(); |
|
1631 |
|
1632 status = generate_nai( |
|
1633 &NAI, |
|
1634 m_use_manual_realm, |
|
1635 get_nai_realm(), |
|
1636 pseudonym, |
|
1637 false, |
|
1638 &m_IMSI, |
|
1639 automatic_realm, |
|
1640 m_length_of_mnc); |
|
1641 if (status != eap_status_ok) |
|
1642 { |
|
1643 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1644 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1645 } |
|
1646 |
|
1647 status = add_pseudonym_or_imsi_payload( |
|
1648 &gsmsim_response, |
|
1649 EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, |
|
1650 gsmsim_response.get_header_length(), |
|
1651 &gsmsim_data_offset, |
|
1652 &gsmsim_data_free, |
|
1653 &packet_buffer_free, |
|
1654 &packet_buffer_offset, |
|
1655 &NAI, |
|
1656 gsmsim_payload_AT_IDENTITY); |
|
1657 if (status != eap_status_ok) |
|
1658 { |
|
1659 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1660 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1661 } |
|
1662 |
|
1663 // Save used NAI. |
|
1664 status = m_NAI.set_copy_of_buffer(&NAI); |
|
1665 if (status != eap_status_ok) |
|
1666 { |
|
1667 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1668 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1669 } |
|
1670 |
|
1671 EAP_TRACE_DEBUG( |
|
1672 m_am_tools, |
|
1673 TRACE_FLAGS_DEFAULT, |
|
1674 (EAPL("eap_type_gsmsim_c::send_start_response_message(): Client sends pseudonym identity.\n"))); |
|
1675 } |
|
1676 else // if (pseudonym->get_is_valid_data() == false) |
|
1677 { |
|
1678 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1679 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); |
|
1680 } |
|
1681 } |
|
1682 else if (m_identity_type == GSMSIM_IDENTITY_TYPE_RE_AUTH_ID) |
|
1683 { |
|
1684 eap_variable_data_c * const reauthentication_identity = &m_reauthentication_identity; |
|
1685 |
|
1686 if (reauthentication_identity->get_is_valid_data() == true) |
|
1687 { |
|
1688 // We have reauthentication identity. Re-authentication identity is NAI. |
|
1689 status = add_pseudonym_or_imsi_payload( |
|
1690 &gsmsim_response, |
|
1691 EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, |
|
1692 gsmsim_response.get_header_length(), |
|
1693 &gsmsim_data_offset, |
|
1694 &gsmsim_data_free, |
|
1695 &packet_buffer_free, |
|
1696 &packet_buffer_offset, |
|
1697 reauthentication_identity, |
|
1698 gsmsim_payload_AT_IDENTITY); |
|
1699 if (status != eap_status_ok) |
|
1700 { |
|
1701 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1702 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1703 } |
|
1704 |
|
1705 // Save used NAI. |
|
1706 status = m_NAI.set_copy_of_buffer(reauthentication_identity); |
|
1707 if (status != eap_status_ok) |
|
1708 { |
|
1709 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1710 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1711 } |
|
1712 |
|
1713 EAP_TRACE_DEBUG( |
|
1714 m_am_tools, |
|
1715 TRACE_FLAGS_DEFAULT, |
|
1716 (EAPL("eap_type_gsmsim_c::send_start_response_message(): Client sends re-authentication identity.\n"))); |
|
1717 } |
|
1718 else |
|
1719 { |
|
1720 // ERROR, no identity available. |
|
1721 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1722 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); |
|
1723 } |
|
1724 } |
|
1725 } |
|
1726 |
|
1727 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
1728 |
|
1729 gsmsim_response.set_data_length( |
|
1730 gsmsim_data_offset, |
|
1731 m_use_eap_expanded_type); |
|
1732 gsmsim_initial_reply.set_data_length(packet_buffer_offset); |
|
1733 |
|
1734 EAP_ASSERT_ALWAYS( |
|
1735 m_gsmsim_header_offset+gsmsim_response.get_header_length()+gsmsim_response.get_data_length() |
|
1736 == packet_buffer_offset); |
|
1737 |
|
1738 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
1739 |
|
1740 status = packet_send( |
|
1741 &send_network_id, |
|
1742 &gsmsim_initial_reply, |
|
1743 m_gsmsim_header_offset, |
|
1744 gsmsim_response.get_header_length()+gsmsim_response.get_data_length(), |
|
1745 EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH |
|
1746 ); |
|
1747 |
|
1748 if (status == eap_status_ok) |
|
1749 { |
|
1750 if (m_authentication_type == GSMSIM_AUTHENTICATION_TYPE_REAUTHENTICATION) |
|
1751 { |
|
1752 // Now we have on-going re-authentication. |
|
1753 set_state(eap_type_gsmsim_state_waiting_for_reauth_request); |
|
1754 } |
|
1755 else |
|
1756 { |
|
1757 // Now we have on-going full-authentication. |
|
1758 set_state(eap_type_gsmsim_state_waiting_for_challenge_request); |
|
1759 } |
|
1760 } |
|
1761 |
|
1762 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
1763 |
|
1764 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1765 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1766 } |
|
1767 |
|
1768 //-------------------------------------------------- |
|
1769 |
|
1770 // |
|
1771 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::send_gsmsim_notification_response( |
|
1772 const eap_gsmsim_notification_codes_e notification_code, |
|
1773 const bool add_at_counter_attribute) |
|
1774 { |
|
1775 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1776 |
|
1777 EAP_TRACE_DEBUG( |
|
1778 m_am_tools, |
|
1779 TRACE_FLAGS_DEFAULT, |
|
1780 (EAPL("send: GSMSIM-type %10s, %s, state %2d=%s\n"), |
|
1781 EAPL("send_gsmsim_notification_response"), |
|
1782 (m_is_client) ? EAPL("client") : EAPL("server"), |
|
1783 m_state, |
|
1784 get_state_string() |
|
1785 )); |
|
1786 |
|
1787 eap_buf_chain_wr_c eap_notification_packet( |
|
1788 eap_write_buffer, |
|
1789 m_am_tools, |
|
1790 EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); |
|
1791 |
|
1792 if (eap_notification_packet.get_is_valid() == false) |
|
1793 { |
|
1794 EAP_TRACE_ERROR( |
|
1795 m_am_tools, |
|
1796 TRACE_FLAGS_DEFAULT, |
|
1797 (EAPL("packet buffer corrupted.\n"))); |
|
1798 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1799 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1800 } |
|
1801 |
|
1802 #if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) |
|
1803 if (m_is_client == true |
|
1804 && m_client_responds_retransmitted_packets == true) |
|
1805 { |
|
1806 // We do not wan't lower layers do re-transmissions behalf of us. |
|
1807 // This means GSMSIM does process every re-transmitted EAP-Request. |
|
1808 eap_notification_packet.set_do_packet_retransmission(false); |
|
1809 } |
|
1810 #endif //#if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) |
|
1811 |
|
1812 EAP_ASSERT_ALWAYS(EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH >= (m_gsmsim_header_offset+m_trailer_length)); |
|
1813 u32_t packet_buffer_free = EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length; |
|
1814 u32_t packet_buffer_offset = 0u; |
|
1815 |
|
1816 if (m_gsmsim_header_offset+m_MTU < packet_buffer_free) |
|
1817 { |
|
1818 packet_buffer_free = m_gsmsim_header_offset+m_MTU; |
|
1819 } |
|
1820 |
|
1821 gsmsim_header_c gsmsim_response( |
|
1822 m_am_tools, |
|
1823 eap_notification_packet.get_data_offset( |
|
1824 m_gsmsim_header_offset, |
|
1825 (packet_buffer_free-m_gsmsim_header_offset)), |
|
1826 (packet_buffer_free-m_gsmsim_header_offset)); |
|
1827 |
|
1828 if (gsmsim_response.get_is_valid() == false) |
|
1829 { |
|
1830 EAP_TRACE_ERROR( |
|
1831 m_am_tools, |
|
1832 TRACE_FLAGS_DEFAULT, |
|
1833 (EAPL("packet_send: packet buffer corrupted.\n"))); |
|
1834 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); |
|
1835 } |
|
1836 |
|
1837 gsmsim_response.reset_header( |
|
1838 static_cast<u16_t>(packet_buffer_free-m_gsmsim_header_offset), |
|
1839 m_use_eap_expanded_type); |
|
1840 gsmsim_response.set_length( |
|
1841 static_cast<u16_t>(packet_buffer_free-m_gsmsim_header_offset), |
|
1842 m_use_eap_expanded_type); |
|
1843 gsmsim_response.set_code(eap_code_response); |
|
1844 gsmsim_response.set_identifier(static_cast<u8_t>(m_last_eap_identifier)); |
|
1845 gsmsim_response.set_type( |
|
1846 eap_type_gsmsim, |
|
1847 m_use_eap_expanded_type); |
|
1848 gsmsim_response.set_subtype(gsmsim_subtype_Notification); |
|
1849 |
|
1850 |
|
1851 update_buffer_indexes( |
|
1852 EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, |
|
1853 m_gsmsim_header_offset+gsmsim_response.get_header_length(), |
|
1854 &packet_buffer_offset, |
|
1855 &packet_buffer_free); |
|
1856 |
|
1857 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
1858 |
|
1859 u32_t gsmsim_data_free = packet_buffer_free; |
|
1860 u32_t gsmsim_data_offset = 0u; |
|
1861 eap_status_e status = eap_status_process_general_error; |
|
1862 |
|
1863 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
1864 |
|
1865 eap_variable_data_c * K_aut = 0; |
|
1866 eap_variable_data_c orig_K_aut(m_am_tools); |
|
1867 |
|
1868 if (get_gsmsim_notification_code_P_bit(notification_code) == false) |
|
1869 { |
|
1870 u8_t *MAC_data = 0; |
|
1871 u32_t MAC_data_length = 0u; |
|
1872 eap_type_gsmsim_MAC_attributes_c MAC_attributes; |
|
1873 |
|
1874 if (add_at_counter_attribute == true) |
|
1875 { |
|
1876 // If EAP-Request/SIM/Notification is used on fast a re-authentication |
|
1877 // exchange, and if the P bit in AT_NOTIFICATION is set to zero, then |
|
1878 // AT_COUNTER is used for replay protection. In this case, the |
|
1879 // AT_ENCR_DATA and AT_IV attributes MUST be included, and the |
|
1880 // encapsulated plaintext attributes MUST include the AT_COUNTER |
|
1881 // attribute. The counter value included in AT_COUNTER MUST be the same |
|
1882 // as in the EAP-Request/SIM/Re-authentication packet on the same fast |
|
1883 // re-authentication exchange. |
|
1884 |
|
1885 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
1886 |
|
1887 eap_variable_data_c orig_XKEY(m_am_tools); |
|
1888 eap_variable_data_c orig_K_encr(m_am_tools); |
|
1889 u32_t reauth_counter = 0u; |
|
1890 |
|
1891 // In order to use re-authentication, the client and the server need to |
|
1892 // store the following values: original XKEY, K_aut, K_encr, latest |
|
1893 // counter value and the next re-authentication identity. |
|
1894 status = m_am_type_gsmsim->query_reauth_parameters( |
|
1895 &orig_XKEY, |
|
1896 &orig_K_aut, |
|
1897 &orig_K_encr, |
|
1898 &reauth_counter); |
|
1899 if (status != eap_status_ok) |
|
1900 { |
|
1901 restore_saved_previous_state(); |
|
1902 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1903 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1904 } |
|
1905 |
|
1906 EAP_TRACE_DEBUG( |
|
1907 m_am_tools, |
|
1908 TRACE_FLAGS_DEFAULT, |
|
1909 (EAPL("eap_type_gsmsim_c::send_gsmsim_notification_response(): %s, m_saved_reauth_counter %d.\n"), |
|
1910 (m_is_client == true ? "client": "server"), |
|
1911 reauth_counter)); |
|
1912 |
|
1913 K_aut = &orig_K_aut; |
|
1914 |
|
1915 // - - - - - - - - - - - - |
|
1916 |
|
1917 crypto_aes_c aes(m_am_tools); |
|
1918 |
|
1919 if (aes.get_is_valid() == false) |
|
1920 { |
|
1921 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1922 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
1923 } |
|
1924 |
|
1925 status = m_am_type_gsmsim->generate_encryption_IV( |
|
1926 m_IV.get_payload_buffer(), |
|
1927 aes.get_block_size()); |
|
1928 if (status != eap_status_ok) |
|
1929 { |
|
1930 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1931 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1932 } |
|
1933 |
|
1934 |
|
1935 status = add_variable_payload( |
|
1936 &gsmsim_response, |
|
1937 EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, |
|
1938 gsmsim_response.get_header_length(), |
|
1939 &gsmsim_data_offset, |
|
1940 &gsmsim_data_free, |
|
1941 &packet_buffer_free, |
|
1942 &packet_buffer_offset, |
|
1943 m_IV.get_payload_buffer(), |
|
1944 gsmsim_payload_AT_IV); |
|
1945 if (status != eap_status_ok) |
|
1946 { |
|
1947 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1948 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1949 } |
|
1950 |
|
1951 |
|
1952 // Encrypted data. |
|
1953 { |
|
1954 gsmsim_payload_AT_header_c gp_encrypted_data( |
|
1955 m_am_tools, |
|
1956 gsmsim_response.get_data_offset( |
|
1957 gsmsim_data_offset, |
|
1958 gsmsim_data_free), |
|
1959 gsmsim_data_free); |
|
1960 if (gsmsim_response.get_is_valid() == false) |
|
1961 { |
|
1962 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1963 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
1964 } |
|
1965 |
|
1966 // Initialize the length of encrypted data to maximum length. |
|
1967 // Later this will be set to correct length. |
|
1968 gp_encrypted_data.reset_header(gsmsim_payload_AT_header_c::get_max_payload_data_length()); |
|
1969 gp_encrypted_data.set_current_payload(gsmsim_payload_AT_ENCR_DATA); |
|
1970 |
|
1971 update_payload_indexes( |
|
1972 EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, |
|
1973 gsmsim_response.get_header_length(), |
|
1974 gp_encrypted_data.get_header_length(), |
|
1975 &gsmsim_data_offset, |
|
1976 &gsmsim_data_free, |
|
1977 &packet_buffer_offset, |
|
1978 &packet_buffer_free); |
|
1979 |
|
1980 u32_t encrypted_data_offset_begin = packet_buffer_offset; |
|
1981 |
|
1982 // - - - - - - - - - - - - |
|
1983 |
|
1984 status = add_counter_payload( |
|
1985 &gsmsim_response, |
|
1986 EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, |
|
1987 gsmsim_response.get_header_length(), |
|
1988 &gsmsim_data_offset, |
|
1989 &gsmsim_data_free, |
|
1990 &packet_buffer_free, |
|
1991 &packet_buffer_offset, |
|
1992 static_cast<u16_t>(reauth_counter)); |
|
1993 if (status != eap_status_ok) |
|
1994 { |
|
1995 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
1996 return EAP_STATUS_RETURN(m_am_tools, status); |
|
1997 } |
|
1998 |
|
1999 // - - - - - - - - - - - - |
|
2000 |
|
2001 status = add_padding_payload( |
|
2002 &gsmsim_response, |
|
2003 EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, |
|
2004 gsmsim_response.get_header_length(), |
|
2005 &gsmsim_data_offset, |
|
2006 &gsmsim_data_free, |
|
2007 &packet_buffer_free, |
|
2008 &packet_buffer_offset, |
|
2009 (packet_buffer_offset - encrypted_data_offset_begin) // Length of the plain text. |
|
2010 ); |
|
2011 if (status != eap_status_ok) |
|
2012 { |
|
2013 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2014 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2015 } |
|
2016 |
|
2017 gp_encrypted_data.set_data_length( |
|
2018 static_cast<u16_t>(packet_buffer_offset - encrypted_data_offset_begin)); |
|
2019 |
|
2020 // - - - - - - - - - - - - |
|
2021 |
|
2022 status = encrypt_DATA_payload( |
|
2023 gp_encrypted_data.get_data(gp_encrypted_data.get_data_length()), |
|
2024 gp_encrypted_data.get_data_length(), |
|
2025 m_IV.get_payload_buffer(), |
|
2026 &orig_K_encr); |
|
2027 if (status != eap_status_ok) |
|
2028 { |
|
2029 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2030 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2031 } |
|
2032 |
|
2033 EAP_GSMSIM_TRACE_PAYLOAD("Payload added", &gp_encrypted_data); |
|
2034 } |
|
2035 |
|
2036 } |
|
2037 else |
|
2038 { |
|
2039 K_aut = &m_K_aut; |
|
2040 } // if (add_counter_payload == true) |
|
2041 |
|
2042 // - - - - - - - - - - - - |
|
2043 |
|
2044 // Add AT_MAC attribute. |
|
2045 status = add_mac_payload( |
|
2046 &gsmsim_response, |
|
2047 EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, |
|
2048 gsmsim_response.get_header_length(), |
|
2049 &gsmsim_data_offset, |
|
2050 &gsmsim_data_free, |
|
2051 &packet_buffer_free, |
|
2052 &packet_buffer_offset, |
|
2053 &MAC_data, |
|
2054 &MAC_data_length); |
|
2055 if (status != eap_status_ok) |
|
2056 { |
|
2057 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2058 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2059 } |
|
2060 |
|
2061 // - - - - - - - - - - - - |
|
2062 |
|
2063 gsmsim_response.set_data_length( |
|
2064 gsmsim_data_offset, |
|
2065 m_use_eap_expanded_type); |
|
2066 eap_notification_packet.set_data_length(packet_buffer_offset); |
|
2067 |
|
2068 EAP_ASSERT_ALWAYS( |
|
2069 m_gsmsim_header_offset+gsmsim_response.get_header_length()+gsmsim_response.get_data_length() |
|
2070 == packet_buffer_offset); |
|
2071 |
|
2072 // - - - - - - - - - - - - |
|
2073 |
|
2074 MAC_attributes.init( |
|
2075 MAC_data, |
|
2076 MAC_data_length, |
|
2077 gsmsim_response.get_header_buffer(gsmsim_response.get_length()), |
|
2078 gsmsim_response.get_length()); |
|
2079 |
|
2080 status = create_message_authentication_code( |
|
2081 &MAC_attributes, |
|
2082 gsmsim_response.get_subtype(), |
|
2083 gsmsim_response.get_code(), |
|
2084 K_aut); |
|
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 else |
|
2092 { |
|
2093 gsmsim_response.set_data_length( |
|
2094 gsmsim_data_offset, |
|
2095 m_use_eap_expanded_type); |
|
2096 |
|
2097 eap_notification_packet.set_data_length(packet_buffer_offset); |
|
2098 |
|
2099 EAP_ASSERT_ALWAYS( |
|
2100 m_gsmsim_header_offset+gsmsim_response.get_header_length()+gsmsim_response.get_data_length() |
|
2101 == packet_buffer_offset); |
|
2102 } |
|
2103 |
|
2104 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
2105 |
|
2106 eap_notification_packet.set_data_length(packet_buffer_offset); |
|
2107 |
|
2108 EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL(" send: EAP-Response/Notification packet"), |
|
2109 gsmsim_response.get_header_buffer(gsmsim_response.get_length()), |
|
2110 gsmsim_response.get_length())); |
|
2111 |
|
2112 status = packet_send( |
|
2113 &m_send_network_id, |
|
2114 &eap_notification_packet, |
|
2115 m_gsmsim_header_offset, |
|
2116 gsmsim_response.get_length(), |
|
2117 EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH |
|
2118 ); |
|
2119 |
|
2120 if (status == eap_status_ok) |
|
2121 { |
|
2122 } |
|
2123 |
|
2124 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
2125 |
|
2126 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2127 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2128 } |
|
2129 |
|
2130 |
|
2131 //-------------------------------------------------- |
|
2132 |
|
2133 // |
|
2134 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::send_gsmsim_client_error_response() |
|
2135 { |
|
2136 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2137 |
|
2138 EAP_TRACE_DEBUG( |
|
2139 m_am_tools, |
|
2140 TRACE_FLAGS_GSMSIM_ERROR, |
|
2141 (EAPL("ERROR: send: GSMSIM-type %10s, %s, state %2d=%s, m_client_error_code %d\n"), |
|
2142 EAPL("send_gsmsim_client_error_response"), |
|
2143 (m_is_client) ? EAPL("client") : EAPL("server"), |
|
2144 m_state, |
|
2145 get_state_string(), |
|
2146 m_client_error_code |
|
2147 )); |
|
2148 |
|
2149 eap_buf_chain_wr_c eap_client_error_packet( |
|
2150 eap_write_buffer, |
|
2151 m_am_tools, |
|
2152 EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); |
|
2153 |
|
2154 if (eap_client_error_packet.get_is_valid() == false) |
|
2155 { |
|
2156 EAP_TRACE_ERROR( |
|
2157 m_am_tools, |
|
2158 TRACE_FLAGS_DEFAULT, |
|
2159 (EAPL("packet buffer corrupted.\n"))); |
|
2160 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2161 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
2162 } |
|
2163 |
|
2164 #if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) |
|
2165 if (m_is_client == true |
|
2166 && m_client_responds_retransmitted_packets == true) |
|
2167 { |
|
2168 // We do not wan't lower layers do re-transmissions behalf of us. |
|
2169 // This means GSMSIM does process every re-transmitted EAP-Request. |
|
2170 eap_client_error_packet.set_do_packet_retransmission(false); |
|
2171 } |
|
2172 #endif //#if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) |
|
2173 |
|
2174 EAP_ASSERT_ALWAYS(EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH >= (m_gsmsim_header_offset+m_trailer_length)); |
|
2175 u32_t packet_buffer_free = EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length; |
|
2176 u32_t packet_buffer_offset = 0u; |
|
2177 |
|
2178 if (m_gsmsim_header_offset+m_MTU < packet_buffer_free) |
|
2179 { |
|
2180 packet_buffer_free = m_gsmsim_header_offset+m_MTU; |
|
2181 } |
|
2182 |
|
2183 gsmsim_header_c gsmsim_response( |
|
2184 m_am_tools, |
|
2185 eap_client_error_packet.get_data_offset( |
|
2186 m_gsmsim_header_offset, |
|
2187 (packet_buffer_free-m_gsmsim_header_offset)), |
|
2188 (packet_buffer_free-m_gsmsim_header_offset)); |
|
2189 |
|
2190 if (gsmsim_response.get_is_valid() == false) |
|
2191 { |
|
2192 EAP_TRACE_ERROR( |
|
2193 m_am_tools, |
|
2194 TRACE_FLAGS_DEFAULT, |
|
2195 (EAPL("packet_send: packet buffer corrupted.\n"))); |
|
2196 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); |
|
2197 } |
|
2198 |
|
2199 gsmsim_response.reset_header( |
|
2200 static_cast<u16_t>(packet_buffer_free-m_gsmsim_header_offset), |
|
2201 m_use_eap_expanded_type); |
|
2202 gsmsim_response.set_length( |
|
2203 static_cast<u16_t>(packet_buffer_free-m_gsmsim_header_offset), |
|
2204 m_use_eap_expanded_type); |
|
2205 gsmsim_response.set_code(eap_code_response); |
|
2206 gsmsim_response.set_identifier(static_cast<u8_t>(m_last_eap_identifier)); |
|
2207 gsmsim_response.set_type( |
|
2208 eap_type_gsmsim, |
|
2209 m_use_eap_expanded_type); |
|
2210 gsmsim_response.set_subtype(gsmsim_subtype_Client_Error); |
|
2211 |
|
2212 |
|
2213 update_buffer_indexes( |
|
2214 EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, |
|
2215 m_gsmsim_header_offset+gsmsim_response.get_header_length(), |
|
2216 &packet_buffer_offset, |
|
2217 &packet_buffer_free); |
|
2218 |
|
2219 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
2220 |
|
2221 u32_t gsmsim_data_free = packet_buffer_free; |
|
2222 u32_t gsmsim_data_offset = 0u; |
|
2223 |
|
2224 eap_status_e status = add_client_error_payload( |
|
2225 &gsmsim_response, |
|
2226 EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, |
|
2227 gsmsim_response.get_header_length(), |
|
2228 &gsmsim_data_offset, |
|
2229 &gsmsim_data_free, |
|
2230 &packet_buffer_free, |
|
2231 &packet_buffer_offset, |
|
2232 m_client_error_code); |
|
2233 if (status != eap_status_ok) |
|
2234 { |
|
2235 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2236 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2237 } |
|
2238 |
|
2239 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
2240 |
|
2241 gsmsim_response.set_data_length( |
|
2242 gsmsim_data_offset, |
|
2243 m_use_eap_expanded_type); |
|
2244 |
|
2245 eap_client_error_packet.set_data_length(packet_buffer_offset); |
|
2246 |
|
2247 EAP_ASSERT_ALWAYS( |
|
2248 m_gsmsim_header_offset+gsmsim_response.get_header_length()+gsmsim_response.get_data_length() |
|
2249 == packet_buffer_offset); |
|
2250 |
|
2251 status = eap_status_process_general_error; |
|
2252 |
|
2253 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
2254 |
|
2255 eap_client_error_packet.set_data_length(packet_buffer_offset); |
|
2256 |
|
2257 EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL(" send: EAP-Response/Client-Error packet"), |
|
2258 gsmsim_response.get_header_buffer(gsmsim_response.get_length()), |
|
2259 gsmsim_response.get_length())); |
|
2260 |
|
2261 status = packet_send( |
|
2262 &m_send_network_id, |
|
2263 &eap_client_error_packet, |
|
2264 m_gsmsim_header_offset, |
|
2265 gsmsim_response.get_length(), |
|
2266 EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH |
|
2267 ); |
|
2268 |
|
2269 if (status == eap_status_ok) |
|
2270 { |
|
2271 } |
|
2272 |
|
2273 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
2274 |
|
2275 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2276 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2277 } |
|
2278 |
|
2279 |
|
2280 //-------------------------------------------------- |
|
2281 |
|
2282 // |
|
2283 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::send_challenge_response_message( |
|
2284 eap_variable_data_c * const K_aut) |
|
2285 { |
|
2286 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2287 |
|
2288 EAP_TRACE_DEBUG( |
|
2289 m_am_tools, |
|
2290 TRACE_FLAGS_DEFAULT, |
|
2291 (EAPL(" send: GSMSIM-type %10s, %s, state %2d=%s\n"), |
|
2292 EAPL("gsmsim_subtype_Challenge"), |
|
2293 (m_is_client) ? EAPL("client") : EAPL("server"), |
|
2294 m_state, |
|
2295 get_state_string() |
|
2296 )); |
|
2297 |
|
2298 eap_buf_chain_wr_c gsmsim_initial_reply( |
|
2299 eap_write_buffer, |
|
2300 m_am_tools, |
|
2301 EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); |
|
2302 |
|
2303 if (gsmsim_initial_reply.get_is_valid() == false) |
|
2304 { |
|
2305 EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n"))); |
|
2306 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2307 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
2308 } |
|
2309 |
|
2310 #if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) |
|
2311 if (m_is_client == true |
|
2312 && m_client_responds_retransmitted_packets == true) |
|
2313 { |
|
2314 // We do not wan't lower layers do re-transmissions behalf of us. |
|
2315 // This means GSMSIM does process every re-transmitted EAP-Request. |
|
2316 gsmsim_initial_reply.set_do_packet_retransmission(false); |
|
2317 } |
|
2318 #endif //#if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) |
|
2319 |
|
2320 EAP_ASSERT_ALWAYS(EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH >= (m_gsmsim_header_offset+m_trailer_length)); |
|
2321 u32_t packet_buffer_free = EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length; |
|
2322 u32_t packet_buffer_offset = 0u; |
|
2323 |
|
2324 if (m_gsmsim_header_offset+m_MTU < packet_buffer_free) |
|
2325 { |
|
2326 packet_buffer_free = m_gsmsim_header_offset+m_MTU; |
|
2327 } |
|
2328 |
|
2329 gsmsim_header_c gsmsim_response( |
|
2330 m_am_tools, |
|
2331 gsmsim_initial_reply.get_data_offset( |
|
2332 m_gsmsim_header_offset, |
|
2333 (packet_buffer_free-m_gsmsim_header_offset)), |
|
2334 (packet_buffer_free-m_gsmsim_header_offset)); |
|
2335 |
|
2336 if (gsmsim_response.get_is_valid() == false) |
|
2337 { |
|
2338 EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet_send: packet buffer corrupted.\n"))); |
|
2339 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
2340 } |
|
2341 |
|
2342 |
|
2343 gsmsim_response.reset_header( |
|
2344 packet_buffer_free, |
|
2345 m_use_eap_expanded_type); |
|
2346 gsmsim_response.set_length( |
|
2347 static_cast<u16_t>(packet_buffer_free-m_gsmsim_header_offset), |
|
2348 m_use_eap_expanded_type); |
|
2349 gsmsim_response.set_code(eap_code_response); |
|
2350 gsmsim_response.set_identifier(m_last_eap_identifier); |
|
2351 gsmsim_response.set_type( |
|
2352 eap_type_gsmsim, |
|
2353 m_use_eap_expanded_type); |
|
2354 gsmsim_response.set_subtype(gsmsim_subtype_Challenge); |
|
2355 |
|
2356 update_buffer_indexes( |
|
2357 EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, |
|
2358 m_gsmsim_header_offset+gsmsim_response.get_header_length(), |
|
2359 &packet_buffer_offset, |
|
2360 &packet_buffer_free); |
|
2361 |
|
2362 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
2363 |
|
2364 EAP_TRACE_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("eap_type_gsmsim_c::send_challenge_response_message(0x%08x).\n"), |
|
2365 this)); |
|
2366 |
|
2367 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
2368 |
|
2369 u32_t gsmsim_data_free = packet_buffer_free; |
|
2370 u32_t gsmsim_data_offset = 0u; |
|
2371 eap_status_e status = eap_status_process_general_error; |
|
2372 |
|
2373 u8_t *MAC_data = 0; |
|
2374 u32_t MAC_data_length = 0u; |
|
2375 eap_type_gsmsim_MAC_attributes_c MAC_attributes; |
|
2376 |
|
2377 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
2378 |
|
2379 if (m_use_result_indication == true) |
|
2380 { |
|
2381 // We support use of protected success indications. |
|
2382 status = add_simple_payload( |
|
2383 &gsmsim_response, |
|
2384 EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, |
|
2385 gsmsim_response.get_header_length(), |
|
2386 &gsmsim_data_offset, |
|
2387 &gsmsim_data_free, |
|
2388 &packet_buffer_free, |
|
2389 &packet_buffer_offset, |
|
2390 gsmsim_payload_AT_RESULT_IND); |
|
2391 if (status != eap_status_ok) |
|
2392 { |
|
2393 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2394 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2395 } |
|
2396 } |
|
2397 |
|
2398 // - - - - - - - - - - - - |
|
2399 |
|
2400 status = add_mac_payload( |
|
2401 &gsmsim_response, |
|
2402 EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, |
|
2403 gsmsim_response.get_header_length(), |
|
2404 &gsmsim_data_offset, |
|
2405 &gsmsim_data_free, |
|
2406 &packet_buffer_free, |
|
2407 &packet_buffer_offset, |
|
2408 &MAC_data, |
|
2409 &MAC_data_length); |
|
2410 if (status != eap_status_ok) |
|
2411 { |
|
2412 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2413 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2414 } |
|
2415 |
|
2416 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
2417 |
|
2418 gsmsim_response.set_data_length( |
|
2419 gsmsim_data_offset, |
|
2420 m_use_eap_expanded_type); |
|
2421 |
|
2422 gsmsim_initial_reply.set_data_length(packet_buffer_offset); |
|
2423 |
|
2424 EAP_ASSERT_ALWAYS( |
|
2425 m_gsmsim_header_offset+gsmsim_response.get_header_length()+gsmsim_response.get_data_length() |
|
2426 == packet_buffer_offset); |
|
2427 |
|
2428 // - - - - - - - - - - - - |
|
2429 |
|
2430 MAC_attributes.init( |
|
2431 MAC_data, |
|
2432 MAC_data_length, |
|
2433 gsmsim_response.get_header_buffer(gsmsim_response.get_length()), |
|
2434 gsmsim_response.get_length()); |
|
2435 |
|
2436 status = create_message_authentication_code( |
|
2437 &MAC_attributes, |
|
2438 gsmsim_response.get_subtype(), |
|
2439 gsmsim_response.get_code(), |
|
2440 K_aut); |
|
2441 if (status != eap_status_ok) |
|
2442 { |
|
2443 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2444 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2445 } |
|
2446 |
|
2447 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
2448 |
|
2449 gsmsim_response.set_data_length( |
|
2450 gsmsim_data_offset, |
|
2451 m_use_eap_expanded_type); |
|
2452 |
|
2453 gsmsim_initial_reply.set_data_length(packet_buffer_offset); |
|
2454 |
|
2455 EAP_ASSERT_ALWAYS( |
|
2456 m_gsmsim_header_offset+gsmsim_response.get_header_length()+gsmsim_response.get_data_length() |
|
2457 == packet_buffer_offset); |
|
2458 |
|
2459 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
2460 |
|
2461 status = packet_send( |
|
2462 &m_send_network_id, |
|
2463 &gsmsim_initial_reply, |
|
2464 m_gsmsim_header_offset, |
|
2465 gsmsim_response.get_header_length()+gsmsim_response.get_data_length(), |
|
2466 EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH |
|
2467 ); |
|
2468 |
|
2469 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
2470 |
|
2471 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2472 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2473 } |
|
2474 |
|
2475 //-------------------------------------------------- |
|
2476 |
|
2477 // |
|
2478 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::send_reauthentication_response_message( |
|
2479 const eap_variable_data_c * const orig_XKEY, |
|
2480 const eap_variable_data_c * const orig_K_aut, |
|
2481 const eap_variable_data_c * const orig_K_encr, |
|
2482 const eap_variable_data_c * const reauth_username, |
|
2483 const eap_variable_data_c * const reauth_nonce_s, |
|
2484 const u16_t reauth_counter, |
|
2485 const u8_t eap_identifier, |
|
2486 const bool include_at_counter_too_small) |
|
2487 { |
|
2488 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2489 |
|
2490 EAP_TRACE_DEBUG( |
|
2491 m_am_tools, |
|
2492 TRACE_FLAGS_DEFAULT, |
|
2493 (EAPL(" send: GSMSIM-subtype %10s, %s, state %2d=%s\n"), |
|
2494 EAPL("gsmsim_subtype_Re_authentication"), |
|
2495 EAPL("client"), |
|
2496 m_state, |
|
2497 get_state_string() |
|
2498 )); |
|
2499 |
|
2500 eap_status_e status = eap_status_process_general_error; |
|
2501 |
|
2502 eap_buf_chain_wr_c request_packet( |
|
2503 eap_write_buffer, |
|
2504 m_am_tools, |
|
2505 EAP_MAX_LOCAL_PACKET_BUFFER_LENGTH); |
|
2506 |
|
2507 if (request_packet.get_is_valid() == false) |
|
2508 { |
|
2509 EAP_TRACE_ERROR(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("packet buffer corrupted.\n"))); |
|
2510 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2511 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
2512 } |
|
2513 |
|
2514 #if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) |
|
2515 if (m_is_client == true |
|
2516 && m_client_responds_retransmitted_packets == true) |
|
2517 { |
|
2518 // We do not wan't lower layers do re-transmissions behalf of us. |
|
2519 // This means GSMSIM does process every re-transmitted EAP-Request. |
|
2520 request_packet.set_do_packet_retransmission(false); |
|
2521 } |
|
2522 #endif //#if defined(USE_EAP_TYPE_GSMSIM_OWN_RE_TRANSMISSION) |
|
2523 |
|
2524 EAP_ASSERT_ALWAYS(EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH >= (m_gsmsim_header_offset+m_trailer_length)); |
|
2525 u32_t packet_buffer_free = EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH-m_trailer_length; |
|
2526 u32_t packet_buffer_offset = 0u; |
|
2527 |
|
2528 if (m_gsmsim_header_offset+m_MTU < packet_buffer_free) |
|
2529 { |
|
2530 packet_buffer_free = m_gsmsim_header_offset+m_MTU; |
|
2531 } |
|
2532 |
|
2533 gsmsim_header_c gsmsim_response( |
|
2534 m_am_tools, |
|
2535 request_packet.get_data_offset( |
|
2536 m_gsmsim_header_offset, |
|
2537 (packet_buffer_free-m_gsmsim_header_offset)), |
|
2538 (packet_buffer_free-m_gsmsim_header_offset)); |
|
2539 |
|
2540 if (gsmsim_response.get_is_valid() == false) |
|
2541 { |
|
2542 EAP_TRACE_ERROR( |
|
2543 m_am_tools, |
|
2544 TRACE_FLAGS_DEFAULT, |
|
2545 (EAPL("send_reauthentication_response_message: packet buffer corrupted.\n"))); |
|
2546 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
2547 } |
|
2548 |
|
2549 gsmsim_response.reset_header( |
|
2550 packet_buffer_free-m_gsmsim_header_offset, |
|
2551 m_use_eap_expanded_type); |
|
2552 gsmsim_response.set_length( |
|
2553 static_cast<u16_t>(packet_buffer_free-m_gsmsim_header_offset), |
|
2554 m_use_eap_expanded_type); |
|
2555 gsmsim_response.set_code(eap_code_response); |
|
2556 gsmsim_response.set_identifier(eap_identifier); |
|
2557 gsmsim_response.set_type( |
|
2558 eap_type_gsmsim, |
|
2559 m_use_eap_expanded_type); |
|
2560 gsmsim_response.set_subtype(gsmsim_subtype_Re_authentication); |
|
2561 |
|
2562 update_buffer_indexes( |
|
2563 EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, |
|
2564 m_gsmsim_header_offset+gsmsim_response.get_header_length(), |
|
2565 &packet_buffer_offset, |
|
2566 &packet_buffer_free); |
|
2567 |
|
2568 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
2569 |
|
2570 EAP_TRACE_DEBUG( |
|
2571 m_am_tools, |
|
2572 TRACE_FLAGS_DEFAULT, |
|
2573 (EAPL("eap_type_gsmsim_c::send_reauthentication_response_message(0x%08x).\n"), |
|
2574 this)); |
|
2575 |
|
2576 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
2577 |
|
2578 u32_t gsmsim_data_free = packet_buffer_free; |
|
2579 u32_t gsmsim_data_offset = 0u; |
|
2580 |
|
2581 eap_variable_data_c master_session_key(m_am_tools); |
|
2582 |
|
2583 status = generate_reauth_shared_secred_keys( |
|
2584 EAP_TYPE_GSMSIM_KEYMAT_SIZE, |
|
2585 orig_XKEY, |
|
2586 reauth_counter, |
|
2587 reauth_username, |
|
2588 reauth_nonce_s, |
|
2589 &master_session_key); |
|
2590 if (status != eap_status_ok) |
|
2591 { |
|
2592 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2593 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2594 } |
|
2595 |
|
2596 // - - - - - - - - - - - - |
|
2597 |
|
2598 if (m_use_result_indication == true) |
|
2599 { |
|
2600 // We support use of protected success indications. |
|
2601 status = add_simple_payload( |
|
2602 &gsmsim_response, |
|
2603 EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, |
|
2604 gsmsim_response.get_header_length(), |
|
2605 &gsmsim_data_offset, |
|
2606 &gsmsim_data_free, |
|
2607 &packet_buffer_free, |
|
2608 &packet_buffer_offset, |
|
2609 gsmsim_payload_AT_RESULT_IND); |
|
2610 if (status != eap_status_ok) |
|
2611 { |
|
2612 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2613 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2614 } |
|
2615 } |
|
2616 |
|
2617 // - - - - - - - - - - - - |
|
2618 |
|
2619 crypto_aes_c aes(m_am_tools); |
|
2620 |
|
2621 if (aes.get_is_valid() == false) |
|
2622 { |
|
2623 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2624 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
2625 } |
|
2626 |
|
2627 status = m_am_type_gsmsim->generate_encryption_IV( |
|
2628 m_IV.get_payload_buffer(), |
|
2629 aes.get_block_size()); |
|
2630 if (status != eap_status_ok) |
|
2631 { |
|
2632 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2633 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2634 } |
|
2635 |
|
2636 |
|
2637 status = add_variable_payload( |
|
2638 &gsmsim_response, |
|
2639 EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, |
|
2640 gsmsim_response.get_header_length(), |
|
2641 &gsmsim_data_offset, |
|
2642 &gsmsim_data_free, |
|
2643 &packet_buffer_free, |
|
2644 &packet_buffer_offset, |
|
2645 m_IV.get_payload_buffer(), |
|
2646 gsmsim_payload_AT_IV); |
|
2647 if (status != eap_status_ok) |
|
2648 { |
|
2649 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2650 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2651 } |
|
2652 |
|
2653 |
|
2654 u8_t *MAC_data = 0; |
|
2655 u32_t MAC_data_length = 0u; |
|
2656 eap_type_gsmsim_MAC_attributes_c MAC_attributes; |
|
2657 |
|
2658 // Encrypted data. |
|
2659 { |
|
2660 gsmsim_payload_AT_header_c gp_encrypted_data( |
|
2661 m_am_tools, |
|
2662 gsmsim_response.get_data_offset( |
|
2663 gsmsim_data_offset, |
|
2664 gsmsim_data_free), |
|
2665 gsmsim_data_free); |
|
2666 if (gp_encrypted_data.get_is_valid() == false) |
|
2667 { |
|
2668 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2669 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_parameter); |
|
2670 } |
|
2671 |
|
2672 // Initialize the length of encrypted data to maximum length. |
|
2673 // Later this will be set to correct length. |
|
2674 gp_encrypted_data.reset_header(gsmsim_payload_AT_header_c::get_max_payload_data_length()); |
|
2675 gp_encrypted_data.set_current_payload(gsmsim_payload_AT_ENCR_DATA); |
|
2676 |
|
2677 update_payload_indexes( |
|
2678 EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, |
|
2679 gsmsim_response.get_header_length(), |
|
2680 gp_encrypted_data.get_header_length(), |
|
2681 &gsmsim_data_offset, |
|
2682 &gsmsim_data_free, |
|
2683 &packet_buffer_offset, |
|
2684 &packet_buffer_free); |
|
2685 |
|
2686 u32_t encrypted_data_offset_begin = packet_buffer_offset; |
|
2687 |
|
2688 |
|
2689 // - - - - - - - - - - - - |
|
2690 |
|
2691 if (include_at_counter_too_small == true) |
|
2692 { |
|
2693 status = add_simple_payload( |
|
2694 &gsmsim_response, |
|
2695 EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, |
|
2696 gsmsim_response.get_header_length(), |
|
2697 &gsmsim_data_offset, |
|
2698 &gsmsim_data_free, |
|
2699 &packet_buffer_free, |
|
2700 &packet_buffer_offset, |
|
2701 gsmsim_payload_AT_COUNTER_TOO_SMALL); |
|
2702 if (status != eap_status_ok) |
|
2703 { |
|
2704 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2705 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2706 } |
|
2707 } |
|
2708 |
|
2709 // - - - - - - - - - - - - |
|
2710 |
|
2711 status = add_counter_payload( |
|
2712 &gsmsim_response, |
|
2713 EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, |
|
2714 gsmsim_response.get_header_length(), |
|
2715 &gsmsim_data_offset, |
|
2716 &gsmsim_data_free, |
|
2717 &packet_buffer_free, |
|
2718 &packet_buffer_offset, |
|
2719 reauth_counter); |
|
2720 if (status != eap_status_ok) |
|
2721 { |
|
2722 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2723 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2724 } |
|
2725 |
|
2726 // - - - - - - - - - - - - |
|
2727 |
|
2728 status = add_padding_payload( |
|
2729 &gsmsim_response, |
|
2730 EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, |
|
2731 gsmsim_response.get_header_length(), |
|
2732 &gsmsim_data_offset, |
|
2733 &gsmsim_data_free, |
|
2734 &packet_buffer_free, |
|
2735 &packet_buffer_offset, |
|
2736 (packet_buffer_offset - encrypted_data_offset_begin) // Length of the plain text. |
|
2737 ); |
|
2738 if (status != eap_status_ok) |
|
2739 { |
|
2740 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2741 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2742 } |
|
2743 |
|
2744 gp_encrypted_data.set_data_length( |
|
2745 static_cast<u16_t>(packet_buffer_offset - encrypted_data_offset_begin)); |
|
2746 |
|
2747 // - - - - - - - - - - - - |
|
2748 |
|
2749 status = encrypt_DATA_payload( |
|
2750 gp_encrypted_data.get_data(gp_encrypted_data.get_data_length()), |
|
2751 gp_encrypted_data.get_data_length(), |
|
2752 m_IV.get_payload_buffer(), |
|
2753 orig_K_encr); |
|
2754 if (status != eap_status_ok) |
|
2755 { |
|
2756 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2757 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2758 } |
|
2759 |
|
2760 EAP_GSMSIM_TRACE_PAYLOAD("Payload added", &gp_encrypted_data); |
|
2761 } |
|
2762 |
|
2763 |
|
2764 |
|
2765 // - - - - - - - - - - - - |
|
2766 |
|
2767 status = add_mac_payload( |
|
2768 &gsmsim_response, |
|
2769 EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH, |
|
2770 gsmsim_response.get_header_length(), |
|
2771 &gsmsim_data_offset, |
|
2772 &gsmsim_data_free, |
|
2773 &packet_buffer_free, |
|
2774 &packet_buffer_offset, |
|
2775 &MAC_data, |
|
2776 &MAC_data_length); |
|
2777 if (status != eap_status_ok) |
|
2778 { |
|
2779 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2780 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2781 } |
|
2782 |
|
2783 // - - - - - - - - - - - - |
|
2784 |
|
2785 gsmsim_response.set_data_length( |
|
2786 gsmsim_data_offset, |
|
2787 m_use_eap_expanded_type); |
|
2788 |
|
2789 request_packet.set_data_length(packet_buffer_offset); |
|
2790 |
|
2791 EAP_ASSERT_ALWAYS( |
|
2792 m_gsmsim_header_offset+gsmsim_response.get_header_length()+gsmsim_response.get_data_length() |
|
2793 == packet_buffer_offset); |
|
2794 |
|
2795 // - - - - - - - - - - - - |
|
2796 |
|
2797 MAC_attributes.init( |
|
2798 MAC_data, |
|
2799 MAC_data_length, |
|
2800 gsmsim_response.get_header_buffer(gsmsim_response.get_length()), |
|
2801 gsmsim_response.get_length()); |
|
2802 |
|
2803 status = create_message_authentication_code( |
|
2804 &MAC_attributes, |
|
2805 gsmsim_response.get_subtype(), |
|
2806 gsmsim_response.get_code(), |
|
2807 orig_K_aut); |
|
2808 if (status != eap_status_ok) |
|
2809 { |
|
2810 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2811 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2812 } |
|
2813 |
|
2814 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
2815 |
|
2816 gsmsim_response.set_data_length( |
|
2817 gsmsim_data_offset, |
|
2818 m_use_eap_expanded_type); |
|
2819 |
|
2820 request_packet.set_data_length(packet_buffer_offset); |
|
2821 |
|
2822 EAP_ASSERT_ALWAYS( |
|
2823 m_gsmsim_header_offset+gsmsim_response.get_header_length()+gsmsim_response.get_data_length() |
|
2824 == packet_buffer_offset); |
|
2825 |
|
2826 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
2827 |
|
2828 EAP_TRACE_DEBUG( |
|
2829 m_am_tools, |
|
2830 TRACE_FLAGS_DEFAULT, |
|
2831 (EAPL("eap_type_gsmsim_c::send_reauthentication_request_message()\n"))); |
|
2832 |
|
2833 status = packet_send( |
|
2834 &m_send_network_id, |
|
2835 &request_packet, |
|
2836 m_gsmsim_header_offset, |
|
2837 gsmsim_response.get_header_length()+gsmsim_response.get_data_length(), |
|
2838 EAP_TYPE_GSMSIM_LOCAL_PACKET_BUFFER_LENGTH |
|
2839 ); |
|
2840 |
|
2841 if (status == eap_status_ok) |
|
2842 { |
|
2843 if (include_at_counter_too_small == false) |
|
2844 { |
|
2845 status = m_master_session_key.set_copy_of_buffer(&master_session_key); |
|
2846 if (status != eap_status_ok) |
|
2847 { |
|
2848 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2849 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2850 } |
|
2851 } |
|
2852 else if (include_at_counter_too_small == true) |
|
2853 { |
|
2854 // The full authentication must follow. |
|
2855 m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH; |
|
2856 } |
|
2857 } |
|
2858 |
|
2859 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
2860 |
|
2861 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2862 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2863 } |
|
2864 |
|
2865 //-------------------------------------------------- |
|
2866 |
|
2867 // |
|
2868 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::decrypt_DATA_payload( |
|
2869 gsmsim_payloads_c * const p_gsmsim_payloads, |
|
2870 const eap_variable_data_c * const encryption_key |
|
2871 ) |
|
2872 { |
|
2873 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2874 |
|
2875 eap_status_e status = eap_status_process_general_error; |
|
2876 |
|
2877 crypto_aes_c aes(m_am_tools); |
|
2878 crypto_cbc_c cbc_aes(m_am_tools, &aes, false); |
|
2879 |
|
2880 if (cbc_aes.get_is_valid() == false) |
|
2881 { |
|
2882 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2883 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
2884 } |
|
2885 |
|
2886 if (cbc_aes.get_is_valid() == false) |
|
2887 { |
|
2888 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2889 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
2890 } |
|
2891 |
|
2892 u32_t aes_key_length = aes.get_key_length(); |
|
2893 if (encryption_key->get_data_length() < aes_key_length) |
|
2894 { |
|
2895 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2896 return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); |
|
2897 } |
|
2898 |
|
2899 if (p_gsmsim_payloads->get_ENCR_DATA()->get_data_length() == 0 |
|
2900 || (p_gsmsim_payloads->get_ENCR_DATA()->get_data_length() % aes_key_length) != 0) |
|
2901 { |
|
2902 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2903 return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); |
|
2904 } |
|
2905 |
|
2906 if (p_gsmsim_payloads->get_IV()->get_payload_included() == false |
|
2907 || p_gsmsim_payloads->get_IV()->get_data_length() == 0u |
|
2908 || encryption_key->get_is_valid_data() == false |
|
2909 || encryption_key->get_data_length() == 0u) |
|
2910 { |
|
2911 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2912 return EAP_STATUS_RETURN(m_am_tools, eap_status_key_error); |
|
2913 } |
|
2914 |
|
2915 if (p_gsmsim_payloads->get_ENCR_DATA()->get_payload_included() == false |
|
2916 || p_gsmsim_payloads->get_ENCR_DATA()->get_data_length() == 0u) |
|
2917 { |
|
2918 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2919 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_data_payload); |
|
2920 } |
|
2921 |
|
2922 |
|
2923 status = cbc_aes.set_decryption_key( |
|
2924 p_gsmsim_payloads->get_IV()->get_data(p_gsmsim_payloads->get_IV()->get_data_length()), |
|
2925 p_gsmsim_payloads->get_IV()->get_data_length(), |
|
2926 encryption_key->get_data(), |
|
2927 aes_key_length); |
|
2928 if (status != eap_status_ok) |
|
2929 { |
|
2930 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2931 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2932 } |
|
2933 |
|
2934 status = cbc_aes.decrypt_data( |
|
2935 p_gsmsim_payloads->get_ENCR_DATA()->get_data(p_gsmsim_payloads->get_ENCR_DATA()->get_data_length()), |
|
2936 p_gsmsim_payloads->get_ENCR_DATA()->get_data_length()); |
|
2937 |
|
2938 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2939 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2940 } |
|
2941 |
|
2942 //-------------------------------------------------- |
|
2943 |
|
2944 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::handle_DATA_payload( |
|
2945 const gsmsim_subtype_e subtype, |
|
2946 gsmsim_payloads_c * const p_gsmsim_payloads |
|
2947 ) |
|
2948 { |
|
2949 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2950 |
|
2951 eap_status_e status = eap_status_process_general_error; |
|
2952 |
|
2953 if (p_gsmsim_payloads->get_ENCR_DATA() == 0 |
|
2954 || p_gsmsim_payloads->get_ENCR_DATA()->get_data_length() == 0u) |
|
2955 { |
|
2956 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2957 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); |
|
2958 } |
|
2959 |
|
2960 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - |
|
2961 |
|
2962 u32_t state_payload_buffer_length = p_gsmsim_payloads->get_ENCR_DATA()->get_data_length(); |
|
2963 const gsmsim_payload_AT_header_c gp_data_payload( |
|
2964 m_am_tools, |
|
2965 p_gsmsim_payloads->get_ENCR_DATA()->get_data(state_payload_buffer_length), |
|
2966 state_payload_buffer_length); |
|
2967 |
|
2968 if (gp_data_payload.get_is_valid() == false) |
|
2969 { |
|
2970 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2971 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
2972 } |
|
2973 |
|
2974 status = parse_gsmsim_payload( |
|
2975 &gp_data_payload, |
|
2976 &state_payload_buffer_length, |
|
2977 p_gsmsim_payloads, |
|
2978 subtype); |
|
2979 if (status != eap_status_ok) |
|
2980 { |
|
2981 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2982 return EAP_STATUS_RETURN(m_am_tools, status); |
|
2983 } |
|
2984 |
|
2985 if (p_gsmsim_payloads->get_NEXT_PSEUDONYM()->get_payload_included() == true) |
|
2986 { |
|
2987 if (p_gsmsim_payloads->get_padding_payload()->get_payload_included() == true |
|
2988 && p_gsmsim_payloads->get_padding_payload()->get_data_length() > 0u) |
|
2989 { |
|
2990 crypto_aes_c aes(m_am_tools); |
|
2991 crypto_cbc_c cbc_aes(m_am_tools, &aes, false); |
|
2992 |
|
2993 if (cbc_aes.get_is_valid() == false) |
|
2994 { |
|
2995 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
2996 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
2997 } |
|
2998 |
|
2999 // Check the padding bytes. |
|
3000 // Must be filled with zero (0x00) bytes. |
|
3001 status = cbc_aes.check_padding_bytes( |
|
3002 p_gsmsim_payloads->get_padding_payload()->get_data(p_gsmsim_payloads->get_padding_payload()->get_data_length()), |
|
3003 p_gsmsim_payloads->get_padding_payload()->get_data_length(), |
|
3004 0ul); |
|
3005 if (status != eap_status_ok) |
|
3006 { |
|
3007 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3008 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3009 } |
|
3010 } |
|
3011 |
|
3012 // GSMSIM AM could store pseudonym to favourite place. |
|
3013 status = m_am_type_gsmsim->store_pseudonym_id( |
|
3014 &m_send_network_id, |
|
3015 p_gsmsim_payloads->get_NEXT_PSEUDONYM()->get_payload_buffer()); |
|
3016 if (status != eap_status_ok) |
|
3017 { |
|
3018 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3019 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3020 } |
|
3021 } |
|
3022 |
|
3023 if (p_gsmsim_payloads->get_NEXT_REAUTH_ID()->get_payload_included() == true) |
|
3024 { |
|
3025 if (p_gsmsim_payloads->get_padding_payload()->get_payload_included() == true |
|
3026 && p_gsmsim_payloads->get_padding_payload()->get_data_length() > 0u) |
|
3027 { |
|
3028 crypto_aes_c aes(m_am_tools); |
|
3029 crypto_cbc_c cbc_aes(m_am_tools, &aes, false); |
|
3030 |
|
3031 if (cbc_aes.get_is_valid() == false) |
|
3032 { |
|
3033 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3034 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
3035 } |
|
3036 |
|
3037 // Check the padding bytes. |
|
3038 // Must be filled with zero (0x00) bytes. |
|
3039 status = cbc_aes.check_padding_bytes( |
|
3040 p_gsmsim_payloads->get_padding_payload()->get_data(p_gsmsim_payloads->get_padding_payload()->get_data_length()), |
|
3041 p_gsmsim_payloads->get_padding_payload()->get_data_length(), |
|
3042 0ul); |
|
3043 if (status != eap_status_ok) |
|
3044 { |
|
3045 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3046 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3047 } |
|
3048 } |
|
3049 |
|
3050 // GSMSIM AM could store pseudonym to favourite place. |
|
3051 status = m_am_type_gsmsim->store_reauthentication_id( |
|
3052 &m_send_network_id, |
|
3053 p_gsmsim_payloads->get_NEXT_REAUTH_ID()->get_payload_buffer()); |
|
3054 if (status != eap_status_ok) |
|
3055 { |
|
3056 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3057 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3058 } |
|
3059 } |
|
3060 else |
|
3061 { |
|
3062 // GSMSIM AM should remove re-authentication identity from favourite place. |
|
3063 |
|
3064 EAP_TRACE_DEBUG( |
|
3065 m_am_tools, |
|
3066 TRACE_FLAGS_DEFAULT, |
|
3067 (EAPL("eap_type_gsmsim_c::handle_DATA_payload(0x%08x): Resets re-authentication identity from database.\n"), |
|
3068 this)); |
|
3069 |
|
3070 status = m_am_type_gsmsim->store_reauthentication_id( |
|
3071 &m_send_network_id, |
|
3072 0); |
|
3073 if (status != eap_status_ok) |
|
3074 { |
|
3075 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3076 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3077 } |
|
3078 |
|
3079 m_reauthentication_identity.reset(); |
|
3080 } |
|
3081 |
|
3082 status = eap_status_ok; |
|
3083 |
|
3084 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3085 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3086 } |
|
3087 |
|
3088 |
|
3089 //-------------------------------------------------- |
|
3090 |
|
3091 // |
|
3092 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::handle_start_request_message( |
|
3093 const eap_am_network_id_c * const receive_network_id, |
|
3094 gsmsim_header_c * const received_gsmsim, |
|
3095 const u32_t /* gsmsim_packet_length */, |
|
3096 gsmsim_payloads_c * const p_gsmsim_payloads) |
|
3097 { |
|
3098 eap_status_e status = eap_status_process_general_error; |
|
3099 |
|
3100 #if defined(USE_EAP_GSMSIM_VERIFY_STATES) |
|
3101 const eap_type_gsmsim_state_variable_e gsmsim_start_request_states[] = |
|
3102 { |
|
3103 eap_type_gsmsim_state_waiting_for_start_request, |
|
3104 eap_type_gsmsim_state_pseydonym_waiting_for_start_request, |
|
3105 eap_type_gsmsim_state_imsi_waiting_for_start_request, |
|
3106 eap_type_gsmsim_state_waiting_for_challenge_request, |
|
3107 eap_type_gsmsim_state_waiting_for_reauth_request, |
|
3108 }; |
|
3109 |
|
3110 if (verify_states(gsmsim_start_request_states, GSMSIM_STATE_COUNT(gsmsim_start_request_states)) == true) |
|
3111 #else |
|
3112 if (m_state == eap_type_gsmsim_state_waiting_for_start_request |
|
3113 || m_state == eap_type_gsmsim_state_pseydonym_waiting_for_start_request |
|
3114 || m_state == eap_type_gsmsim_state_imsi_waiting_for_start_request |
|
3115 || m_state == eap_type_gsmsim_state_waiting_for_challenge_request |
|
3116 || m_state == eap_type_gsmsim_state_waiting_for_reauth_request) |
|
3117 #endif //#if defined(USE_EAP_GSMSIM_VERIFY_STATES) |
|
3118 { |
|
3119 // This could be first or retransmission request. |
|
3120 |
|
3121 // Checks the payloads existence. |
|
3122 if (p_gsmsim_payloads->check_payloads( |
|
3123 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_mt |
|
3124 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_s |
|
3125 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // MAC |
|
3126 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // ENCR_DATA |
|
3127 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // IDENTITY |
|
3128 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // padding |
|
3129 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // n_RANDs |
|
3130 gsmsim_payloads_c::eap_gsmsim_payload_status_optional, // PERMANENT_ID_REQ |
|
3131 gsmsim_payloads_c::eap_gsmsim_payload_status_optional, // FULLAUTH_ID_REQ |
|
3132 gsmsim_payloads_c::eap_gsmsim_payload_status_optional, // ANY_ID_REQ |
|
3133 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // IV |
|
3134 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_PSEUDONYM |
|
3135 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_REAUTH_ID |
|
3136 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NOTIFICATION |
|
3137 gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // VERSION_LIST |
|
3138 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // SELECTED_VERSION |
|
3139 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER |
|
3140 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER_TOO_SMALL |
|
3141 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // CLIENT_ERROR_CODE |
|
3142 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be // RESULT_IND |
|
3143 ) == true |
|
3144 ) |
|
3145 { |
|
3146 // NOTE, this message is unauthenticated. Anybody could sent this message. |
|
3147 |
|
3148 bool includes_other_version_than_1 = false; |
|
3149 |
|
3150 eap_gsmsim_version selected_version = select_version( |
|
3151 p_gsmsim_payloads->get_VERSION_LIST(), |
|
3152 &includes_other_version_than_1); |
|
3153 |
|
3154 if (selected_version == GSMSIM_ILLEGAL_VERSION) |
|
3155 { |
|
3156 // ERROR, no supported version. |
|
3157 EAP_TRACE_ERROR( |
|
3158 m_am_tools, |
|
3159 TRACE_FLAGS_GSMSIM_ERROR, |
|
3160 (EAPL("ERROR: eap_type_gsmsim_c::handle_start_request_message(0x%08x), illegal version list.\n"), |
|
3161 this)); |
|
3162 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3163 return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version); |
|
3164 } |
|
3165 |
|
3166 if (p_gsmsim_payloads->get_includes_unknown_attribute() != gsmsim_payload_NONE |
|
3167 && includes_other_version_than_1 == false) |
|
3168 { |
|
3169 // EAP-SIM version 1 must NOT include unknown attributes. |
|
3170 EAP_TRACE_ERROR( |
|
3171 m_am_tools, |
|
3172 TRACE_FLAGS_GSMSIM_ERROR, |
|
3173 (EAPL("ERROR: eap_type_gsmsim_c::handle_start_request_message(0x%08x), illegal payload %d=0x%04x.\n"), |
|
3174 this, |
|
3175 p_gsmsim_payloads->get_includes_unknown_attribute(), |
|
3176 p_gsmsim_payloads->get_includes_unknown_attribute())); |
|
3177 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3178 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
3179 } |
|
3180 |
|
3181 gsmsim_payload_AT_type_e include_identity_to_start_response = gsmsim_payload_NONE; |
|
3182 |
|
3183 |
|
3184 { |
|
3185 if ((p_gsmsim_payloads->get_PERMANENT_ID_REQ()->get_payload_included() == true |
|
3186 && p_gsmsim_payloads->get_FULLAUTH_ID_REQ()->get_payload_included() == true) |
|
3187 || (p_gsmsim_payloads->get_PERMANENT_ID_REQ()->get_payload_included() == true |
|
3188 && p_gsmsim_payloads->get_ANY_ID_REQ()->get_payload_included() == true) |
|
3189 || (p_gsmsim_payloads->get_FULLAUTH_ID_REQ()->get_payload_included() == true |
|
3190 && p_gsmsim_payloads->get_ANY_ID_REQ()->get_payload_included() == true)) |
|
3191 { |
|
3192 // Only one of these is allowed. |
|
3193 EAP_TRACE_ERROR( |
|
3194 m_am_tools, |
|
3195 TRACE_FLAGS_GSMSIM_ERROR, |
|
3196 (EAPL("ERROR: eap_type_gsmsim_c::handle_start_request_message(0x%08x), illegal payloads.\n"), |
|
3197 this)); |
|
3198 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3199 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
3200 } |
|
3201 else if (p_gsmsim_payloads->get_PERMANENT_ID_REQ()->get_payload_included() == true) |
|
3202 { |
|
3203 EAP_TRACE_DEBUG( |
|
3204 m_am_tools, |
|
3205 TRACE_FLAGS_DEFAULT, |
|
3206 (EAPL("eap_type_gsmsim_c::handle_start_request_message ") |
|
3207 EAPL("gsmsim_payload_AT_PERMANENT_ID_REQ\n"))); |
|
3208 // Note, this is optional, included only when pseudonym decode failed in server. |
|
3209 include_identity_to_start_response = gsmsim_payload_AT_PERMANENT_ID_REQ; |
|
3210 } |
|
3211 else if (p_gsmsim_payloads->get_FULLAUTH_ID_REQ()->get_payload_included() == true) |
|
3212 { |
|
3213 EAP_TRACE_DEBUG( |
|
3214 m_am_tools, |
|
3215 TRACE_FLAGS_DEFAULT, |
|
3216 (EAPL("eap_type_gsmsim_c::handle_start_request_message ") |
|
3217 EAPL("gsmsim_payload_AT_FULLAUTH_ID_REQ\n"))); |
|
3218 // Note, this is optional, included only when reauthentication identity decode failed in server. |
|
3219 include_identity_to_start_response = gsmsim_payload_AT_FULLAUTH_ID_REQ; |
|
3220 } |
|
3221 else if (p_gsmsim_payloads->get_ANY_ID_REQ()->get_payload_included() == true) |
|
3222 { |
|
3223 EAP_TRACE_DEBUG( |
|
3224 m_am_tools, |
|
3225 TRACE_FLAGS_DEFAULT, |
|
3226 (EAPL("eap_type_gsmsim_c::handle_start_request_message ") |
|
3227 EAPL("gsmsim_payload_AT_ANY_ID_REQ\n"))); |
|
3228 // Note, this is optional, included only when server have no identity of client. |
|
3229 include_identity_to_start_response = gsmsim_payload_AT_ANY_ID_REQ; |
|
3230 } |
|
3231 } |
|
3232 |
|
3233 if (m_nonce_mt.get_is_valid_data() == false) |
|
3234 { |
|
3235 // Note, if this message is retransmitted request the NONCE_MT |
|
3236 // is already generated. |
|
3237 status = generate_nonce(EAP_TYPE_GSMSIM_NONCE_MT_SIZE, &m_nonce_mt); |
|
3238 if (status != eap_status_ok) |
|
3239 { |
|
3240 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3241 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3242 } |
|
3243 } |
|
3244 |
|
3245 u32_t version_payload_length = p_gsmsim_payloads->get_VERSION_LIST()->get_original_header()->get_data_length(); |
|
3246 u32_t real_payload_length = p_gsmsim_payloads->get_VERSION_LIST()->get_original_header()->get_reserved(); |
|
3247 |
|
3248 if (real_payload_length == 0 |
|
3249 || real_payload_length > version_payload_length) |
|
3250 { |
|
3251 return EAP_STATUS_RETURN(m_am_tools, eap_status_no_matching_protocol_version); |
|
3252 } |
|
3253 |
|
3254 u32_t version_count = real_payload_length/sizeof(u16_t); |
|
3255 u16_t *payload_version_list = reinterpret_cast<u16_t *>(p_gsmsim_payloads->get_VERSION_LIST() |
|
3256 ->get_original_header()->get_data(real_payload_length)); |
|
3257 |
|
3258 status = save_version(payload_version_list, version_count, selected_version); |
|
3259 if (status != eap_status_ok) |
|
3260 { |
|
3261 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3262 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3263 } |
|
3264 |
|
3265 m_include_identity_to_start_response = include_identity_to_start_response; |
|
3266 |
|
3267 |
|
3268 if (include_identity_to_start_response == gsmsim_payload_NONE |
|
3269 && (m_identity.get_is_valid_data() == false)) |
|
3270 { |
|
3271 // We must query the previous sent EAP-Identity from EAP_Core. |
|
3272 // The EAP_Core saves the sent EAP-Identity when the EAP-Identity is |
|
3273 // sent to the network. |
|
3274 // Previous EAP-type was NOT this instance. EAP-Identity was queried from other instance. |
|
3275 status = get_type_partner()->get_saved_eap_identity(&m_identity); |
|
3276 if (status != eap_status_ok) |
|
3277 { |
|
3278 // We do not have the identity server accepted anymore. |
|
3279 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3280 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3281 } |
|
3282 |
|
3283 status = m_NAI.set_copy_of_buffer(&m_identity); |
|
3284 if (status != eap_status_ok) |
|
3285 { |
|
3286 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3287 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3288 } |
|
3289 } |
|
3290 |
|
3291 |
|
3292 if (include_identity_to_start_response == gsmsim_payload_AT_ANY_ID_REQ |
|
3293 && (m_reauthentication_identity.get_is_valid_data() == false |
|
3294 && m_pseudonym.get_is_valid_data() == false |
|
3295 && m_IMSI.get_is_valid_data() == false |
|
3296 && m_automatic_realm_read == false)) |
|
3297 { |
|
3298 eap_variable_data_c IMSI(m_am_tools); |
|
3299 eap_variable_data_c pseudonym(m_am_tools); |
|
3300 eap_variable_data_c reauthentication_identity(m_am_tools); |
|
3301 |
|
3302 EAP_TRACE_DEBUG( |
|
3303 m_am_tools, |
|
3304 TRACE_FLAGS_DEFAULT, |
|
3305 (EAPL("eap_type_gsmsim_c::handle_start_request_message ") |
|
3306 EAPL("gsmsim_payload_AT_ANY_ID_REQ\n"))); |
|
3307 |
|
3308 status = query_SIM_IMSI_or_pseudonym_or_reauthentication_id( |
|
3309 &IMSI, |
|
3310 &pseudonym, |
|
3311 &reauthentication_identity, |
|
3312 &m_automatic_realm, |
|
3313 &m_length_of_mnc, |
|
3314 false, |
|
3315 include_identity_to_start_response, |
|
3316 eap_type_gsmsim_complete_start_request, |
|
3317 received_gsmsim->get_identifier()); |
|
3318 |
|
3319 if (status == eap_status_pending_request) |
|
3320 { |
|
3321 // This is pending query, that will be completed by complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() call. |
|
3322 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3323 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3324 } |
|
3325 else if (status == eap_status_completed_request) |
|
3326 { |
|
3327 // This is already completed by complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() call. |
|
3328 EAP_TRACE_DEBUG( |
|
3329 m_am_tools, |
|
3330 TRACE_FLAGS_DEFAULT, |
|
3331 (EAPL("eap_type_gsmsim_c::handle_start_request_message(): ") |
|
3332 EAPL("completed returns eap_type_gsmsim_state_variable_e %d=%s.\n"), |
|
3333 m_state, |
|
3334 get_state_string())); |
|
3335 |
|
3336 status = eap_status_ok; |
|
3337 |
|
3338 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3339 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3340 } |
|
3341 else if (status != eap_status_ok) |
|
3342 { |
|
3343 // This is the error case. |
|
3344 |
|
3345 EAP_TRACE_ERROR( |
|
3346 m_am_tools, |
|
3347 TRACE_FLAGS_DEFAULT, |
|
3348 (EAPL("eap_type_gsmsim_c::handle_start_request_message(): ") |
|
3349 EAPL("error returns eap_type_gsmsim_state_variable_e %d=%s.\n"), |
|
3350 m_state, |
|
3351 get_state_string())); |
|
3352 |
|
3353 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3354 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3355 } |
|
3356 |
|
3357 if (reauthentication_identity.get_is_valid_data() == true) |
|
3358 { |
|
3359 EAP_TRACE_DEBUG( |
|
3360 m_am_tools, |
|
3361 TRACE_FLAGS_DEFAULT, |
|
3362 (EAPL("eap_type_gsmsim_c::handle_start_request_message ") |
|
3363 EAPL("reauthentication_identity\n"))); |
|
3364 |
|
3365 status = m_reauthentication_identity.set_copy_of_buffer(&reauthentication_identity); |
|
3366 if (status != eap_status_ok) |
|
3367 { |
|
3368 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3369 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3370 } |
|
3371 |
|
3372 status = store_identity(&m_reauthentication_identity, false); |
|
3373 if (status != eap_status_ok) |
|
3374 { |
|
3375 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3376 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3377 } |
|
3378 } |
|
3379 else if (pseudonym.get_is_valid_data() == true) |
|
3380 { |
|
3381 EAP_TRACE_DEBUG( |
|
3382 m_am_tools, |
|
3383 TRACE_FLAGS_DEFAULT, |
|
3384 (EAPL("eap_type_gsmsim_c::handle_start_request_message pseudonym\n"))); |
|
3385 |
|
3386 m_reauthentication_identity.reset(); |
|
3387 status = m_pseudonym.set_copy_of_buffer(&pseudonym); |
|
3388 if (status != eap_status_ok) |
|
3389 { |
|
3390 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3391 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3392 } |
|
3393 |
|
3394 status = store_identity(&m_pseudonym, false); |
|
3395 if (status != eap_status_ok) |
|
3396 { |
|
3397 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3398 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3399 } |
|
3400 } |
|
3401 else if (IMSI.get_is_valid_data() == true) |
|
3402 { |
|
3403 EAP_TRACE_DEBUG( |
|
3404 m_am_tools, |
|
3405 TRACE_FLAGS_DEFAULT, |
|
3406 (EAPL("eap_type_gsmsim_c::handle_start_request_message IMSI\n"))); |
|
3407 |
|
3408 m_reauthentication_identity.reset(); |
|
3409 m_pseudonym.reset(); |
|
3410 status = m_IMSI.set_copy_of_buffer(&IMSI); |
|
3411 if (status != eap_status_ok) |
|
3412 { |
|
3413 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3414 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3415 } |
|
3416 |
|
3417 status = store_identity(&m_IMSI, true); |
|
3418 if (status != eap_status_ok) |
|
3419 { |
|
3420 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3421 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3422 } |
|
3423 } |
|
3424 } |
|
3425 else if (include_identity_to_start_response == gsmsim_payload_AT_FULLAUTH_ID_REQ |
|
3426 && (m_pseudonym.get_is_valid_data() == false |
|
3427 && m_IMSI.get_is_valid_data() == false |
|
3428 && m_automatic_realm_read == false)) |
|
3429 { |
|
3430 eap_variable_data_c IMSI(m_am_tools); |
|
3431 eap_variable_data_c pseudonym(m_am_tools); |
|
3432 eap_variable_data_c reauthentication_identity(m_am_tools); |
|
3433 |
|
3434 EAP_TRACE_DEBUG( |
|
3435 m_am_tools, |
|
3436 TRACE_FLAGS_DEFAULT, |
|
3437 (EAPL("eap_type_gsmsim_c::handle_start_request_message ") |
|
3438 EAPL("gsmsim_payload_AT_FULLAUTH_ID_REQ\n"))); |
|
3439 |
|
3440 status = query_SIM_IMSI_or_pseudonym_or_reauthentication_id( |
|
3441 &IMSI, |
|
3442 &pseudonym, |
|
3443 &reauthentication_identity, |
|
3444 &m_automatic_realm, |
|
3445 &m_length_of_mnc, |
|
3446 false, |
|
3447 include_identity_to_start_response, |
|
3448 eap_type_gsmsim_complete_start_request, |
|
3449 received_gsmsim->get_identifier()); |
|
3450 |
|
3451 if (status == eap_status_pending_request) |
|
3452 { |
|
3453 // This is pending query, that will be completed by complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() call. |
|
3454 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3455 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3456 } |
|
3457 else if (status == eap_status_completed_request) |
|
3458 { |
|
3459 // This is already completed by complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() call. |
|
3460 EAP_TRACE_DEBUG( |
|
3461 m_am_tools, |
|
3462 TRACE_FLAGS_DEFAULT, |
|
3463 (EAPL("eap_type_gsmsim_c::handle_start_request_message(): ") |
|
3464 EAPL("completed returns eap_type_gsmsim_state_variable_e %d=%s.\n"), |
|
3465 m_state, |
|
3466 get_state_string())); |
|
3467 |
|
3468 status = eap_status_ok; |
|
3469 |
|
3470 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3471 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3472 } |
|
3473 else if (status != eap_status_ok) |
|
3474 { |
|
3475 // This is the error case. |
|
3476 |
|
3477 EAP_TRACE_ERROR( |
|
3478 m_am_tools, |
|
3479 TRACE_FLAGS_DEFAULT, |
|
3480 (EAPL("eap_type_gsmsim_c::handle_start_request_message(): ") |
|
3481 EAPL("error returns eap_type_gsmsim_state_variable_e %d=%s.\n"), |
|
3482 m_state, |
|
3483 get_state_string())); |
|
3484 |
|
3485 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3486 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3487 } |
|
3488 |
|
3489 if (pseudonym.get_is_valid_data() == true) |
|
3490 { |
|
3491 EAP_TRACE_DEBUG( |
|
3492 m_am_tools, |
|
3493 TRACE_FLAGS_DEFAULT, |
|
3494 (EAPL("eap_type_gsmsim_c::handle_start_request_message pseudonym\n"))); |
|
3495 |
|
3496 m_reauthentication_identity.reset(); |
|
3497 status = m_pseudonym.set_copy_of_buffer(&pseudonym); |
|
3498 if (status != eap_status_ok) |
|
3499 { |
|
3500 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3501 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3502 } |
|
3503 |
|
3504 status = store_identity(&m_pseudonym, false); |
|
3505 if (status != eap_status_ok) |
|
3506 { |
|
3507 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3508 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3509 } |
|
3510 } |
|
3511 else if (IMSI.get_is_valid_data() == true) |
|
3512 { |
|
3513 EAP_TRACE_DEBUG( |
|
3514 m_am_tools, |
|
3515 TRACE_FLAGS_DEFAULT, |
|
3516 (EAPL("eap_type_gsmsim_c::handle_start_request_message IMSI\n"))); |
|
3517 |
|
3518 m_reauthentication_identity.reset(); |
|
3519 m_pseudonym.reset(); |
|
3520 status = m_IMSI.set_copy_of_buffer(&IMSI); |
|
3521 if (status != eap_status_ok) |
|
3522 { |
|
3523 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3524 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3525 } |
|
3526 |
|
3527 status = store_identity(&m_IMSI, true); |
|
3528 if (status != eap_status_ok) |
|
3529 { |
|
3530 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3531 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3532 } |
|
3533 } |
|
3534 } |
|
3535 else if (include_identity_to_start_response == gsmsim_payload_AT_PERMANENT_ID_REQ |
|
3536 && m_IMSI.get_is_valid_data() == false |
|
3537 && m_automatic_realm_read == false) |
|
3538 { |
|
3539 eap_variable_data_c IMSI(m_am_tools); |
|
3540 eap_variable_data_c pseudonym(m_am_tools); |
|
3541 eap_variable_data_c reauthentication_identity(m_am_tools); |
|
3542 |
|
3543 EAP_TRACE_DEBUG( |
|
3544 m_am_tools, |
|
3545 TRACE_FLAGS_DEFAULT, |
|
3546 (EAPL("eap_type_gsmsim_c::handle_start_request_message ") |
|
3547 EAPL("gsmsim_payload_AT_PERMANENT_ID_REQ\n"))); |
|
3548 |
|
3549 status = query_SIM_IMSI_or_pseudonym_or_reauthentication_id( |
|
3550 &IMSI, |
|
3551 &pseudonym, |
|
3552 &reauthentication_identity, |
|
3553 &m_automatic_realm, |
|
3554 &m_length_of_mnc, |
|
3555 false, |
|
3556 include_identity_to_start_response, |
|
3557 eap_type_gsmsim_complete_start_request, |
|
3558 received_gsmsim->get_identifier()); |
|
3559 |
|
3560 if (status == eap_status_pending_request) |
|
3561 { |
|
3562 // This is pending query, that will be completed by complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() call. |
|
3563 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3564 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3565 } |
|
3566 else if (status == eap_status_completed_request) |
|
3567 { |
|
3568 // This is already completed by complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() call. |
|
3569 EAP_TRACE_DEBUG( |
|
3570 m_am_tools, |
|
3571 TRACE_FLAGS_DEFAULT, |
|
3572 (EAPL("eap_type_gsmsim_c::handle_start_request_message(): ") |
|
3573 EAPL("completed returns eap_type_gsmsim_state_variable_e %d=%s.\n"), |
|
3574 m_state, |
|
3575 get_state_string())); |
|
3576 |
|
3577 status = eap_status_ok; |
|
3578 |
|
3579 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3580 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3581 } |
|
3582 else if (status != eap_status_ok) |
|
3583 { |
|
3584 // This is the error case. |
|
3585 |
|
3586 EAP_TRACE_ERROR( |
|
3587 m_am_tools, |
|
3588 TRACE_FLAGS_DEFAULT, |
|
3589 (EAPL("eap_type_gsmsim_c::handle_start_request_message(): ") |
|
3590 EAPL("error returns eap_type_gsmsim_state_variable_e %d=%s.\n"), |
|
3591 m_state, |
|
3592 get_state_string())); |
|
3593 |
|
3594 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3595 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3596 } |
|
3597 |
|
3598 if (IMSI.get_is_valid_data() == true) |
|
3599 { |
|
3600 EAP_TRACE_DEBUG( |
|
3601 m_am_tools, |
|
3602 TRACE_FLAGS_DEFAULT, |
|
3603 (EAPL("eap_type_gsmsim_c::handle_start_request_message IMSI\n"))); |
|
3604 |
|
3605 m_reauthentication_identity.reset(); |
|
3606 m_pseudonym.reset(); |
|
3607 status = m_IMSI.set_copy_of_buffer(&IMSI); |
|
3608 if (status != eap_status_ok) |
|
3609 { |
|
3610 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3611 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3612 } |
|
3613 |
|
3614 status = store_identity(&m_IMSI, true); |
|
3615 if (status != eap_status_ok) |
|
3616 { |
|
3617 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3618 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3619 } |
|
3620 } |
|
3621 else |
|
3622 { |
|
3623 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3624 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3625 } |
|
3626 } |
|
3627 |
|
3628 |
|
3629 save_current_state(); |
|
3630 set_state(eap_type_gsmsim_state_analyse_start_request); |
|
3631 |
|
3632 EAP_TRACE_DEBUG( |
|
3633 m_am_tools, |
|
3634 TRACE_FLAGS_DEFAULT, |
|
3635 (EAPL("eap_type_gsmsim_c::handle_start_request_message(0x%08x).\n"), |
|
3636 this)); |
|
3637 |
|
3638 status = send_start_response_message( |
|
3639 receive_network_id, |
|
3640 received_gsmsim->get_identifier(), |
|
3641 selected_version, |
|
3642 include_identity_to_start_response, |
|
3643 &m_automatic_realm, |
|
3644 m_length_of_mnc); |
|
3645 |
|
3646 if (status != eap_status_ok) |
|
3647 { |
|
3648 restore_saved_previous_state(); |
|
3649 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3650 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3651 } |
|
3652 } |
|
3653 else |
|
3654 { |
|
3655 // Not correct GSMSIM-payloads are included. |
|
3656 EAP_TRACE_ERROR( |
|
3657 m_am_tools, |
|
3658 TRACE_FLAGS_GSMSIM_ERROR, |
|
3659 (EAPL("ERROR: eap_type_gsmsim_c::handle_start_request_message(1): ") |
|
3660 EAPL("Not correct GSMSIM-payloads are included in eap_type_gsmsim_state_variable_e %d=%s.\n"), |
|
3661 m_state, |
|
3662 get_state_string())); |
|
3663 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3664 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
3665 } |
|
3666 } |
|
3667 else |
|
3668 { |
|
3669 // Wrong message in this state. |
|
3670 EAP_TRACE_ERROR( |
|
3671 m_am_tools, |
|
3672 TRACE_FLAGS_GSMSIM_ERROR, |
|
3673 (EAPL("ERROR: eap_type_gsmsim_c::handle_start_request_message(): ") |
|
3674 EAPL("Wrong message %d=%s in eap_type_gsmsim_state_variable_e %d=%s.\n"), |
|
3675 received_gsmsim->get_subtype(), |
|
3676 received_gsmsim->get_subtype_string(), |
|
3677 m_state, |
|
3678 get_state_string())); |
|
3679 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3680 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
3681 } |
|
3682 |
|
3683 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3684 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3685 } |
|
3686 |
|
3687 |
|
3688 //-------------------------------------------------- |
|
3689 |
|
3690 // |
|
3691 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::handle_gsmsim_notification_request_message_reauthentication( |
|
3692 const eap_am_network_id_c * const receive_network_id, |
|
3693 gsmsim_header_c * const received_gsmsim, |
|
3694 const u32_t /*gsmsim_packet_length*/, |
|
3695 gsmsim_payloads_c * const p_gsmsim_payloads) |
|
3696 { |
|
3697 eap_status_e status = eap_status_process_general_error; |
|
3698 |
|
3699 EAP_TRACE_DEBUG( |
|
3700 m_am_tools, |
|
3701 TRACE_FLAGS_DEFAULT, |
|
3702 (EAPL("send: GSMSIM-type %10s, %s, state %2d=%s\n"), |
|
3703 EAPL("handle_gsmsim_notification_request_message_reauthentication"), |
|
3704 (m_is_client) ? EAPL("client") : EAPL("server"), |
|
3705 m_state, |
|
3706 get_state_string() |
|
3707 )); |
|
3708 |
|
3709 #if defined(USE_EAP_GSMSIM_VERIFY_STATES) |
|
3710 const eap_type_gsmsim_state_variable_e gsmsim_notification_request_message_reauthentication_states_1[] = |
|
3711 { |
|
3712 eap_type_gsmsim_state_waiting_for_success, |
|
3713 eap_type_gsmsim_state_success, |
|
3714 eap_type_gsmsim_state_waiting_for_notification_request_success, |
|
3715 }; |
|
3716 |
|
3717 const eap_type_gsmsim_state_variable_e gsmsim_notification_request_message_reauthentication_states_2[] = |
|
3718 { |
|
3719 eap_type_gsmsim_state_waiting_for_identity_request, |
|
3720 eap_type_gsmsim_state_pending_identity_query, |
|
3721 eap_type_gsmsim_state_waiting_for_start_request, |
|
3722 eap_type_gsmsim_state_imsi_waiting_for_start_request, |
|
3723 eap_type_gsmsim_state_pseydonym_waiting_for_start_request, |
|
3724 eap_type_gsmsim_state_analyse_start_request, |
|
3725 eap_type_gsmsim_state_waiting_for_challenge_request, |
|
3726 eap_type_gsmsim_state_analyses_challenge_request, |
|
3727 eap_type_gsmsim_state_pending_kc_sres_query, |
|
3728 eap_type_gsmsim_state_waiting_for_reauth_request, |
|
3729 eap_type_gsmsim_state_analyses_reauthentication_request, |
|
3730 eap_type_gsmsim_state_waiting_for_success, |
|
3731 eap_type_gsmsim_state_success, |
|
3732 eap_type_gsmsim_state_waiting_for_notification_request_success, |
|
3733 eap_type_gsmsim_state_failure, |
|
3734 }; |
|
3735 |
|
3736 if (get_gsmsim_notification_code_P_bit(m_gsmsim_notification_code) == false |
|
3737 && verify_states(gsmsim_notification_request_message_reauthentication_states_1, |
|
3738 GSMSIM_STATE_COUNT(gsmsim_notification_request_message_reauthentication_states_1)) == true) |
|
3739 #else |
|
3740 // The second most significant bit of the notification code is called |
|
3741 // the Phase bit (P bit). It specifies at which phase of the EAP-SIM |
|
3742 // exchange the notification can be used. |
|
3743 if (get_gsmsim_notification_code_P_bit(m_gsmsim_notification_code) == false |
|
3744 && (m_state == eap_type_gsmsim_state_waiting_for_success |
|
3745 || m_state == eap_type_gsmsim_state_success |
|
3746 || m_state == eap_type_gsmsim_state_waiting_for_notification_request_success) |
|
3747 ) |
|
3748 #endif //#if defined(USE_EAP_GSMSIM_VERIFY_STATES) |
|
3749 { |
|
3750 // If the P bit is set to zero, |
|
3751 // the notification can only be used after a successful EAP/SIM/ |
|
3752 // Challenge round in full authentication or a successful EAP/SIM/ |
|
3753 // Re-authentication round in reautentication. A re-authentication round |
|
3754 // is considered successful only if the peer has successfully verified |
|
3755 // AT_MAC and AT_COUNTER attributes, and does not include the |
|
3756 // AT_COUNTER_TOO_SMALL attribute in EAP-Response/SIM/Re-authentication. |
|
3757 |
|
3758 // The AT_MAC attribute MUST beincluded if the P bit of the notification |
|
3759 // code in AT_NOTIFICATION is set to zero, and MUST NOT be included in |
|
3760 // cases when the P bit is set to one. The P bit is discussed in Section |
|
3761 // 4.4. |
|
3762 if (p_gsmsim_payloads->check_payloads( |
|
3763 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_mt |
|
3764 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_s |
|
3765 gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // MAC |
|
3766 gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // ENCR_DATA |
|
3767 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // IDENTITY |
|
3768 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // padding |
|
3769 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // n_RANDs |
|
3770 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // PERMANENT_ID_REQ |
|
3771 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // FULLAUTH_ID_REQ |
|
3772 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // ANY_ID_REQ |
|
3773 gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // IV |
|
3774 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_PSEUDONYM |
|
3775 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_REAUTH_ID |
|
3776 gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // NOTIFICATION |
|
3777 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // VERSION_LIST |
|
3778 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // SELECTED_VERSION |
|
3779 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER |
|
3780 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER_TOO_SMALL |
|
3781 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // CLIENT_ERROR_CODE |
|
3782 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be // RESULT_IND |
|
3783 ) == true |
|
3784 ) |
|
3785 { |
|
3786 eap_variable_data_c orig_XKEY(m_am_tools); |
|
3787 eap_variable_data_c orig_K_aut(m_am_tools); |
|
3788 eap_variable_data_c orig_K_encr(m_am_tools); |
|
3789 u32_t reauth_counter = 0u; |
|
3790 |
|
3791 // In order to use re-authentication, the client and the server need to |
|
3792 // store the following values: original XKEY, K_aut, K_encr, latest |
|
3793 // counter value and the next re-authentication identity. |
|
3794 status = m_am_type_gsmsim->query_reauth_parameters( |
|
3795 &orig_XKEY, |
|
3796 &orig_K_aut, |
|
3797 &orig_K_encr, |
|
3798 &reauth_counter); |
|
3799 if (status != eap_status_ok) |
|
3800 { |
|
3801 restore_saved_previous_state(); |
|
3802 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3803 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3804 } |
|
3805 |
|
3806 EAP_TRACE_DEBUG( |
|
3807 m_am_tools, |
|
3808 TRACE_FLAGS_DEFAULT, |
|
3809 (EAPL("eap_type_gsmsim_c::handle_gsmsim_notification_request_message_reauthentication(): %s, m_saved_reauth_counter %d.\n"), |
|
3810 (m_is_client == true ? "client": "server"), |
|
3811 reauth_counter)); |
|
3812 |
|
3813 status = check_message_authentication_code( |
|
3814 &orig_K_aut, |
|
3815 p_gsmsim_payloads, |
|
3816 received_gsmsim, |
|
3817 received_gsmsim->get_length()); |
|
3818 if (status != eap_status_ok) |
|
3819 { |
|
3820 (void) initialize_error_message(status); |
|
3821 |
|
3822 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3823 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3824 } |
|
3825 |
|
3826 bool authentication_ok = true; |
|
3827 |
|
3828 // Decrypt and parse encrypted payload. |
|
3829 { |
|
3830 gsmsim_payloads_c * const l_gsmsim_payloads = new gsmsim_payloads_c(m_am_tools); |
|
3831 eap_automatic_variable_c<gsmsim_payloads_c> l_gsmsim_payloads_automatic(m_am_tools, l_gsmsim_payloads); |
|
3832 |
|
3833 if (l_gsmsim_payloads == 0 |
|
3834 || l_gsmsim_payloads->get_is_valid() == false) |
|
3835 { |
|
3836 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3837 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
3838 } |
|
3839 |
|
3840 status = decrypt_DATA_payload( |
|
3841 p_gsmsim_payloads, |
|
3842 &orig_K_encr); |
|
3843 if (status != eap_status_ok) |
|
3844 { |
|
3845 restore_saved_previous_state(); |
|
3846 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3847 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3848 } |
|
3849 |
|
3850 u32_t state_payload_buffer_length = p_gsmsim_payloads->get_ENCR_DATA()->get_data_length(); |
|
3851 const gsmsim_payload_AT_header_c gp_data_payload( |
|
3852 m_am_tools, |
|
3853 p_gsmsim_payloads->get_ENCR_DATA()->get_data(state_payload_buffer_length), |
|
3854 state_payload_buffer_length); |
|
3855 |
|
3856 status = parse_gsmsim_payload( |
|
3857 &gp_data_payload, |
|
3858 &state_payload_buffer_length, |
|
3859 l_gsmsim_payloads, |
|
3860 received_gsmsim->get_subtype()); |
|
3861 if (status != eap_status_ok) |
|
3862 { |
|
3863 restore_saved_previous_state(); |
|
3864 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3865 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3866 } |
|
3867 |
|
3868 |
|
3869 if (l_gsmsim_payloads->get_COUNTER()->get_payload_included() == false) |
|
3870 { |
|
3871 restore_saved_previous_state(); |
|
3872 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3873 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); |
|
3874 } |
|
3875 |
|
3876 u32_t counter = l_gsmsim_payloads->get_COUNTER()->get_original_header()->get_reserved(); |
|
3877 |
|
3878 if (counter == reauth_counter) |
|
3879 { |
|
3880 EAP_TRACE_DEBUG( |
|
3881 m_am_tools, |
|
3882 TRACE_FLAGS_DEFAULT, |
|
3883 (EAPL("eap_type_gsmsim_c::handle_gsmsim_notification_request_message_reauthentication(): ") |
|
3884 EAPL("reauth counter %d OK, %d=%s.\n"), |
|
3885 reauth_counter, |
|
3886 m_state, |
|
3887 get_state_string())); |
|
3888 } |
|
3889 else |
|
3890 { |
|
3891 EAP_TRACE_ERROR( |
|
3892 m_am_tools, |
|
3893 TRACE_FLAGS_GSMSIM_ERROR, |
|
3894 (EAPL("ERROR: eap_type_gsmsim_c::handle_gsmsim_notification_request_message_reauthentication(): ") |
|
3895 EAPL("reauth counter %d wrong, should be %d, %d=%s.\n"), |
|
3896 counter, |
|
3897 reauth_counter, |
|
3898 m_state, |
|
3899 get_state_string())); |
|
3900 |
|
3901 authentication_ok = false; |
|
3902 } |
|
3903 } |
|
3904 |
|
3905 |
|
3906 bool do_increase_reauth_counter(false); |
|
3907 |
|
3908 // The most significant bit is called the Failure bit (F bit). |
|
3909 // The F bit specifies whether the notification implies failure. |
|
3910 if (authentication_ok == false |
|
3911 || get_gsmsim_notification_code_F_bit(m_gsmsim_notification_code) == false) |
|
3912 { |
|
3913 // The code values with the F bit set to zero (code values 0...32767) |
|
3914 // are used on unsuccessful cases. |
|
3915 // The receipt of a notification code from this range implies failed EAP |
|
3916 // exchange, so the peer can use the notification as a failure indication. |
|
3917 |
|
3918 set_state(eap_type_gsmsim_state_failure); |
|
3919 |
|
3920 // This will terminate session immediately. |
|
3921 get_type_partner()->set_session_timeout(0ul); |
|
3922 } |
|
3923 else //if (get_gsmsim_notification_code_F_bit(m_gsmsim_notification_code) == true) |
|
3924 { |
|
3925 // The receipt of a notification code with the F bit set to one (values |
|
3926 // 32768...65536) does not imply failure. Notification code 32768 has |
|
3927 // been reserved as a general notification code to indicate successful |
|
3928 // authentication. |
|
3929 if (m_gsmsim_notification_code == eap_gsmsim_notification_F_set_no_P_user_authenticated) |
|
3930 { |
|
3931 do_increase_reauth_counter = true; |
|
3932 |
|
3933 if (m_wait_eap_success_packet == false) |
|
3934 { |
|
3935 status = finish_successful_authentication( |
|
3936 receive_network_id); |
|
3937 if (status != eap_status_ok) |
|
3938 { |
|
3939 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3940 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3941 } |
|
3942 } |
|
3943 else |
|
3944 { |
|
3945 // This version waits the EAP-Success message. |
|
3946 set_state(eap_type_gsmsim_state_waiting_for_success); |
|
3947 status = eap_status_ok; |
|
3948 |
|
3949 EAP_TRACE_DEBUG( |
|
3950 m_am_tools, |
|
3951 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
3952 (EAPL("EAP_type_GSMSIM: %s, re-authentication OK, waits EAP-Success\n"), |
|
3953 (m_is_client == true) ? "client": "server")); |
|
3954 } |
|
3955 } |
|
3956 } |
|
3957 |
|
3958 status = send_gsmsim_notification_response( |
|
3959 m_gsmsim_notification_code, |
|
3960 true); |
|
3961 if (status != eap_status_ok) |
|
3962 { |
|
3963 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3964 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3965 } |
|
3966 |
|
3967 if (do_increase_reauth_counter == true) |
|
3968 { |
|
3969 // Re-authentication counter is increased only on first time. |
|
3970 // In order to use re-authentication, the client and the server need to |
|
3971 // update re-authentication counter value. |
|
3972 status = m_am_type_gsmsim->increase_reauth_counter(); |
|
3973 if (status != eap_status_ok) |
|
3974 { |
|
3975 restore_saved_previous_state(); |
|
3976 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3977 return EAP_STATUS_RETURN(m_am_tools, status); |
|
3978 } |
|
3979 } |
|
3980 } |
|
3981 else |
|
3982 { |
|
3983 // Not correct GSMSIM-payloads are included. |
|
3984 EAP_TRACE_ERROR( |
|
3985 m_am_tools, |
|
3986 TRACE_FLAGS_GSMSIM_ERROR, |
|
3987 (EAPL("ERROR: eap_type_gsmsim_c::handle_gsmsim_notification_request_message(1): ") |
|
3988 EAPL("Not correct GSMSIM-payloads are included in eap_type_gsmsim_state_variable_e %d=%s.\n"), |
|
3989 m_state, |
|
3990 get_state_string())); |
|
3991 |
|
3992 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
3993 return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); |
|
3994 } |
|
3995 } |
|
3996 #if defined(USE_EAP_GSMSIM_VERIFY_STATES) |
|
3997 else if (get_gsmsim_notification_code_P_bit(m_gsmsim_notification_code) == true |
|
3998 && verify_states(gsmsim_notification_request_message_reauthentication_states_2, |
|
3999 GSMSIM_STATE_COUNT(gsmsim_notification_request_message_reauthentication_states_2)) == true) |
|
4000 #else |
|
4001 else if (get_gsmsim_notification_code_P_bit(m_gsmsim_notification_code) == true |
|
4002 && (m_state == eap_type_gsmsim_state_waiting_for_identity_request |
|
4003 || m_state == eap_type_gsmsim_state_pending_identity_query |
|
4004 || m_state == eap_type_gsmsim_state_waiting_for_start_request |
|
4005 || m_state == eap_type_gsmsim_state_imsi_waiting_for_start_request |
|
4006 || m_state == eap_type_gsmsim_state_pseydonym_waiting_for_start_request |
|
4007 || m_state == eap_type_gsmsim_state_analyse_start_request |
|
4008 || m_state == eap_type_gsmsim_state_waiting_for_challenge_request |
|
4009 || m_state == eap_type_gsmsim_state_analyses_challenge_request |
|
4010 || m_state == eap_type_gsmsim_state_pending_kc_sres_query |
|
4011 || m_state == eap_type_gsmsim_state_waiting_for_reauth_request |
|
4012 || m_state == eap_type_gsmsim_state_analyses_reauthentication_request |
|
4013 || m_state == eap_type_gsmsim_state_waiting_for_success |
|
4014 || m_state == eap_type_gsmsim_state_success |
|
4015 || m_state == eap_type_gsmsim_state_waiting_for_notification_request_success |
|
4016 || m_state == eap_type_gsmsim_state_failure)) |
|
4017 #endif //#if defined(USE_EAP_GSMSIM_VERIFY_STATES) |
|
4018 { |
|
4019 // If the P bit is set to one, the notification can only by used before |
|
4020 // the EAP/SIM/Challenge round in full authentication, or before the |
|
4021 // EAP/SIM/Re-authentication round in reauthentication. |
|
4022 |
|
4023 // The most significant bit is called the Failure bit (F bit). |
|
4024 // The F bit specifies whether the notification implies failure. |
|
4025 if (get_gsmsim_notification_code_F_bit(m_gsmsim_notification_code) == false) |
|
4026 { |
|
4027 // The code values with the F bit set to zero (code values 0...32767) |
|
4028 // are used on unsuccessful cases. |
|
4029 // The receipt of a notification code from this range implies failed EAP |
|
4030 // exchange, so the peer can use the notification as a failure indication. |
|
4031 } |
|
4032 else //if (get_gsmsim_notification_code_F_bit(m_gsmsim_notification_code) == true) |
|
4033 { |
|
4034 // The receipt of a notification code with the F bit set to one (values |
|
4035 // 32768...65536) does not imply failure. Notification code 32768 has |
|
4036 // been reserved as a general notification code to indicate successful |
|
4037 // authentication. |
|
4038 } |
|
4039 |
|
4040 status = initialize_notification_message(); |
|
4041 if (status != eap_status_ok) |
|
4042 { |
|
4043 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4044 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4045 } |
|
4046 } |
|
4047 else |
|
4048 { |
|
4049 // Wrong message in this state. |
|
4050 EAP_TRACE_ERROR( |
|
4051 m_am_tools, |
|
4052 TRACE_FLAGS_GSMSIM_ERROR, |
|
4053 (EAPL("ERROR: eap_type_gsmsim_c::handle_gsmsim_notification_request_message(): ") |
|
4054 EAPL("Wrong message %d=%s in eap_type_gsmsim_state_variable_e %d=%s.\n"), |
|
4055 received_gsmsim->get_subtype(), |
|
4056 received_gsmsim->get_subtype_string(), |
|
4057 m_state, |
|
4058 get_state_string())); |
|
4059 |
|
4060 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4061 return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); |
|
4062 } |
|
4063 |
|
4064 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4065 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4066 } |
|
4067 |
|
4068 //-------------------------------------------------- |
|
4069 |
|
4070 // |
|
4071 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::handle_gsmsim_notification_request_message_full_authentication( |
|
4072 const eap_am_network_id_c * const receive_network_id, |
|
4073 gsmsim_header_c * const received_gsmsim, |
|
4074 const u32_t /*gsmsim_packet_length*/, |
|
4075 gsmsim_payloads_c * const p_gsmsim_payloads) |
|
4076 { |
|
4077 eap_status_e status = eap_status_process_general_error; |
|
4078 |
|
4079 EAP_TRACE_DEBUG( |
|
4080 m_am_tools, |
|
4081 TRACE_FLAGS_DEFAULT, |
|
4082 (EAPL("send: GSMSIM-type %10s, %s, state %2d=%s\n"), |
|
4083 EAPL("handle_gsmsim_notification_request_message_full_authentication"), |
|
4084 (m_is_client) ? EAPL("client") : EAPL("server"), |
|
4085 m_state, |
|
4086 get_state_string() |
|
4087 )); |
|
4088 |
|
4089 #if defined(USE_EAP_GSMSIM_VERIFY_STATES) |
|
4090 const eap_type_gsmsim_state_variable_e gsmsim_notification_request_message_full_authentication_states_1[] = |
|
4091 { |
|
4092 eap_type_gsmsim_state_waiting_for_success, |
|
4093 eap_type_gsmsim_state_success, |
|
4094 eap_type_gsmsim_state_waiting_for_notification_request_success, |
|
4095 }; |
|
4096 |
|
4097 const eap_type_gsmsim_state_variable_e gsmsim_notification_request_message_full_authentication_states_2[] = |
|
4098 { |
|
4099 eap_type_gsmsim_state_waiting_for_identity_request, |
|
4100 eap_type_gsmsim_state_pending_identity_query, |
|
4101 eap_type_gsmsim_state_waiting_for_start_request, |
|
4102 eap_type_gsmsim_state_imsi_waiting_for_start_request, |
|
4103 eap_type_gsmsim_state_pseydonym_waiting_for_start_request, |
|
4104 eap_type_gsmsim_state_analyse_start_request, |
|
4105 eap_type_gsmsim_state_waiting_for_challenge_request, |
|
4106 eap_type_gsmsim_state_analyses_challenge_request, |
|
4107 eap_type_gsmsim_state_pending_kc_sres_query, |
|
4108 eap_type_gsmsim_state_waiting_for_reauth_request, |
|
4109 eap_type_gsmsim_state_analyses_reauthentication_request, |
|
4110 eap_type_gsmsim_state_waiting_for_success, |
|
4111 eap_type_gsmsim_state_success, |
|
4112 eap_type_gsmsim_state_waiting_for_notification_request_success, |
|
4113 eap_type_gsmsim_state_failure, |
|
4114 }; |
|
4115 |
|
4116 if (get_gsmsim_notification_code_P_bit(m_gsmsim_notification_code) == false |
|
4117 && verify_states(gsmsim_notification_request_message_full_authentication_states_1, |
|
4118 GSMSIM_STATE_COUNT(gsmsim_notification_request_message_full_authentication_states_1)) == true) |
|
4119 #else |
|
4120 // The second most significant bit of the notification code is called |
|
4121 // the Phase bit (P bit). It specifies at which phase of the EAP-SIM |
|
4122 // exchange the notification can be used. |
|
4123 if (get_gsmsim_notification_code_P_bit(m_gsmsim_notification_code) == false |
|
4124 && (m_state == eap_type_gsmsim_state_waiting_for_success |
|
4125 || m_state == eap_type_gsmsim_state_success |
|
4126 || m_state == eap_type_gsmsim_state_waiting_for_notification_request_success) |
|
4127 ) |
|
4128 #endif //#if defined(USE_EAP_GSMSIM_VERIFY_STATES) |
|
4129 { |
|
4130 // If the P bit is set to zero, |
|
4131 // the notification can only be used after a successful EAP/SIM/ |
|
4132 // Challenge round in full authentication or a successful EAP/SIM/ |
|
4133 // Re-authentication round in reautentication. A re-authentication round |
|
4134 // is considered successful only if the peer has successfully verified |
|
4135 // AT_MAC and AT_COUNTER attributes, and does not include the |
|
4136 // AT_COUNTER_TOO_SMALL attribute in EAP-Response/SIM/Re-authentication. |
|
4137 |
|
4138 // The AT_MAC attribute MUST beincluded if the P bit of the notification |
|
4139 // code in AT_NOTIFICATION is set to zero, and MUST NOT be included in |
|
4140 // cases when the P bit is set to one. The P bit is discussed in Section |
|
4141 // 4.4. |
|
4142 if (p_gsmsim_payloads->check_payloads( |
|
4143 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_mt |
|
4144 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_s |
|
4145 gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // MAC |
|
4146 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // ENCR_DATA |
|
4147 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // IDENTITY |
|
4148 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // padding |
|
4149 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // n_RANDs |
|
4150 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // PERMANENT_ID_REQ |
|
4151 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // FULLAUTH_ID_REQ |
|
4152 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // ANY_ID_REQ |
|
4153 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // IV |
|
4154 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_PSEUDONYM |
|
4155 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_REAUTH_ID |
|
4156 gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // NOTIFICATION |
|
4157 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // VERSION_LIST |
|
4158 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // SELECTED_VERSION |
|
4159 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER |
|
4160 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER_TOO_SMALL |
|
4161 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // CLIENT_ERROR_CODE |
|
4162 gsmsim_payloads_c::eap_gsmsim_payload_status_optional // RESULT_IND |
|
4163 ) == true |
|
4164 ) |
|
4165 { |
|
4166 status = check_message_authentication_code( |
|
4167 &m_K_aut, |
|
4168 p_gsmsim_payloads, |
|
4169 received_gsmsim, |
|
4170 received_gsmsim->get_length()); |
|
4171 if (status != eap_status_ok) |
|
4172 { |
|
4173 (void) initialize_error_message(status); |
|
4174 |
|
4175 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4176 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4177 } |
|
4178 |
|
4179 if (m_use_result_indication == false |
|
4180 && m_gsmsim_notification_code == eap_gsmsim_notification_F_set_no_P_user_authenticated) |
|
4181 { |
|
4182 // ERROR: We did not require result indication and server send it to us. |
|
4183 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4184 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); |
|
4185 } |
|
4186 |
|
4187 // The most significant bit is called the Failure bit (F bit). |
|
4188 // The F bit specifies whether the notification implies failure. |
|
4189 if (get_gsmsim_notification_code_F_bit(m_gsmsim_notification_code) == false) |
|
4190 { |
|
4191 // The code values with the F bit set to zero (code values 0...32767) |
|
4192 // are used on unsuccessful cases. |
|
4193 // The receipt of a notification code from this range implies failed EAP |
|
4194 // exchange, so the peer can use the notification as a failure indication. |
|
4195 |
|
4196 set_state(eap_type_gsmsim_state_failure); |
|
4197 |
|
4198 // This will terminate session immediately. |
|
4199 get_type_partner()->set_session_timeout(0ul); |
|
4200 } |
|
4201 else //if (get_gsmsim_notification_code_F_bit(m_gsmsim_notification_code) == true) |
|
4202 { |
|
4203 // The receipt of a notification code with the F bit set to one (values |
|
4204 // 32768...65536) does not imply failure. Notification code 32768 has |
|
4205 // been reserved as a general notification code to indicate successful |
|
4206 // authentication. |
|
4207 if (m_gsmsim_notification_code == eap_gsmsim_notification_F_set_no_P_user_authenticated) |
|
4208 { |
|
4209 if (m_wait_eap_success_packet == false) |
|
4210 { |
|
4211 status = finish_successful_authentication( |
|
4212 receive_network_id); |
|
4213 if (status != eap_status_ok) |
|
4214 { |
|
4215 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4216 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4217 } |
|
4218 } |
|
4219 else |
|
4220 { |
|
4221 // This version waits the EAP-Success message. |
|
4222 set_state(eap_type_gsmsim_state_waiting_for_success); |
|
4223 status = eap_status_ok; |
|
4224 |
|
4225 EAP_TRACE_DEBUG( |
|
4226 m_am_tools, |
|
4227 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
4228 (EAPL("EAP_type_GSMSIM: %s, full-authentication OK, waits EAP-Success\n"), |
|
4229 (m_is_client == true) ? "client": "server")); |
|
4230 } |
|
4231 } |
|
4232 } |
|
4233 |
|
4234 status = send_gsmsim_notification_response( |
|
4235 m_gsmsim_notification_code, |
|
4236 false); |
|
4237 if (status != eap_status_ok) |
|
4238 { |
|
4239 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4240 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4241 } |
|
4242 } |
|
4243 else |
|
4244 { |
|
4245 // Not correct GSMSIM-payloads are included. |
|
4246 EAP_TRACE_ERROR( |
|
4247 m_am_tools, |
|
4248 TRACE_FLAGS_GSMSIM_ERROR, |
|
4249 (EAPL("ERROR: eap_type_gsmsim_c::handle_gsmsim_notification_request_message(1): ") |
|
4250 EAPL("Not correct GSMSIM-payloads are included in eap_type_gsmsim_state_variable_e %d=%s.\n"), |
|
4251 m_state, |
|
4252 get_state_string())); |
|
4253 |
|
4254 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4255 return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); |
|
4256 } |
|
4257 } |
|
4258 #if defined(USE_EAP_GSMSIM_VERIFY_STATES) |
|
4259 else if (get_gsmsim_notification_code_P_bit(m_gsmsim_notification_code) == true |
|
4260 && verify_states(gsmsim_notification_request_message_full_authentication_states_2, |
|
4261 GSMSIM_STATE_COUNT(gsmsim_notification_request_message_full_authentication_states_2)) == true) |
|
4262 #else |
|
4263 else if (get_gsmsim_notification_code_P_bit(m_gsmsim_notification_code) == true |
|
4264 && (m_state == eap_type_gsmsim_state_waiting_for_identity_request |
|
4265 || m_state == eap_type_gsmsim_state_pending_identity_query |
|
4266 || m_state == eap_type_gsmsim_state_waiting_for_start_request |
|
4267 || m_state == eap_type_gsmsim_state_imsi_waiting_for_start_request |
|
4268 || m_state == eap_type_gsmsim_state_pseydonym_waiting_for_start_request |
|
4269 || m_state == eap_type_gsmsim_state_analyse_start_request |
|
4270 || m_state == eap_type_gsmsim_state_waiting_for_challenge_request |
|
4271 || m_state == eap_type_gsmsim_state_analyses_challenge_request |
|
4272 || m_state == eap_type_gsmsim_state_pending_kc_sres_query |
|
4273 || m_state == eap_type_gsmsim_state_waiting_for_reauth_request |
|
4274 || m_state == eap_type_gsmsim_state_analyses_reauthentication_request |
|
4275 || m_state == eap_type_gsmsim_state_waiting_for_success |
|
4276 || m_state == eap_type_gsmsim_state_success |
|
4277 || m_state == eap_type_gsmsim_state_waiting_for_notification_request_success |
|
4278 || m_state == eap_type_gsmsim_state_failure)) |
|
4279 #endif //#if defined(USE_EAP_GSMSIM_VERIFY_STATES) |
|
4280 { |
|
4281 // If the P bit is set to one, the notification can only by used before |
|
4282 // the EAP/SIM/Challenge round in full authentication, or before the |
|
4283 // EAP/SIM/Re-authentication round in reauthentication. |
|
4284 |
|
4285 // The most significant bit is called the Failure bit (F bit). |
|
4286 // The F bit specifies whether the notification implies failure. |
|
4287 if (get_gsmsim_notification_code_F_bit(m_gsmsim_notification_code) == false) |
|
4288 { |
|
4289 // The code values with the F bit set to zero (code values 0...32767) |
|
4290 // are used on unsuccessful cases. |
|
4291 // The receipt of a notification code from this range implies failed EAP |
|
4292 // exchange, so the peer can use the notification as a failure indication. |
|
4293 } |
|
4294 else //if (get_gsmsim_notification_code_F_bit(m_gsmsim_notification_code) == true) |
|
4295 { |
|
4296 // The receipt of a notification code with the F bit set to one (values |
|
4297 // 32768...65536) does not imply failure. Notification code 32768 has |
|
4298 // been reserved as a general notification code to indicate successful |
|
4299 // authentication. |
|
4300 } |
|
4301 |
|
4302 status = initialize_notification_message(); |
|
4303 if (status != eap_status_ok) |
|
4304 { |
|
4305 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4306 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4307 } |
|
4308 } |
|
4309 else |
|
4310 { |
|
4311 // Wrong message in this state. |
|
4312 EAP_TRACE_ERROR( |
|
4313 m_am_tools, |
|
4314 TRACE_FLAGS_GSMSIM_ERROR, |
|
4315 (EAPL("ERROR: eap_type_gsmsim_c::handle_gsmsim_notification_request_message(): ") |
|
4316 EAPL("Wrong message %d=%s in eap_type_gsmsim_state_variable_e %d=%s.\n"), |
|
4317 received_gsmsim->get_subtype(), |
|
4318 received_gsmsim->get_subtype_string(), |
|
4319 m_state, |
|
4320 get_state_string())); |
|
4321 |
|
4322 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4323 return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); |
|
4324 } |
|
4325 |
|
4326 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4327 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4328 } |
|
4329 |
|
4330 //-------------------------------------------------- |
|
4331 |
|
4332 // |
|
4333 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::handle_gsmsim_notification_request_message( |
|
4334 const eap_am_network_id_c * const receive_network_id, |
|
4335 gsmsim_header_c * const received_gsmsim, |
|
4336 const u32_t gsmsim_packet_length, |
|
4337 gsmsim_payloads_c * const p_gsmsim_payloads) |
|
4338 { |
|
4339 eap_status_e status = eap_status_process_general_error; |
|
4340 |
|
4341 EAP_UNREFERENCED_PARAMETER(received_gsmsim); |
|
4342 EAP_UNREFERENCED_PARAMETER(gsmsim_packet_length); |
|
4343 EAP_UNREFERENCED_PARAMETER(receive_network_id); |
|
4344 |
|
4345 #if defined(USE_EAP_GSMSIM_VERIFY_STATES) |
|
4346 const eap_type_gsmsim_state_variable_e gsmsim_notification_request_message_states[] = |
|
4347 { |
|
4348 eap_type_gsmsim_state_waiting_for_identity_request, |
|
4349 eap_type_gsmsim_state_pending_identity_query, |
|
4350 eap_type_gsmsim_state_waiting_for_start_request, |
|
4351 eap_type_gsmsim_state_imsi_waiting_for_start_request, |
|
4352 eap_type_gsmsim_state_pseydonym_waiting_for_start_request, |
|
4353 eap_type_gsmsim_state_analyse_start_request, |
|
4354 eap_type_gsmsim_state_waiting_for_challenge_request, |
|
4355 eap_type_gsmsim_state_analyses_challenge_request, |
|
4356 eap_type_gsmsim_state_pending_kc_sres_query, |
|
4357 eap_type_gsmsim_state_waiting_for_notification_request_success, |
|
4358 eap_type_gsmsim_state_waiting_for_success, |
|
4359 eap_type_gsmsim_state_waiting_for_reauth_request, |
|
4360 eap_type_gsmsim_state_analyses_reauthentication_request, |
|
4361 eap_type_gsmsim_state_success, |
|
4362 eap_type_gsmsim_state_failure, |
|
4363 }; |
|
4364 |
|
4365 if (verify_states(gsmsim_notification_request_message_states, |
|
4366 GSMSIM_STATE_COUNT(gsmsim_notification_request_message_states)) == true) |
|
4367 #else |
|
4368 if (m_state == eap_type_gsmsim_state_waiting_for_identity_request |
|
4369 || m_state == eap_type_gsmsim_state_pending_identity_query |
|
4370 || m_state == eap_type_gsmsim_state_waiting_for_start_request |
|
4371 || m_state == eap_type_gsmsim_state_imsi_waiting_for_start_request |
|
4372 || m_state == eap_type_gsmsim_state_pseydonym_waiting_for_start_request |
|
4373 || m_state == eap_type_gsmsim_state_analyse_start_request |
|
4374 || m_state == eap_type_gsmsim_state_waiting_for_challenge_request |
|
4375 || m_state == eap_type_gsmsim_state_analyses_challenge_request |
|
4376 || m_state == eap_type_gsmsim_state_pending_kc_sres_query |
|
4377 || m_state == eap_type_gsmsim_state_waiting_for_notification_request_success |
|
4378 || m_state == eap_type_gsmsim_state_waiting_for_success |
|
4379 || m_state == eap_type_gsmsim_state_waiting_for_reauth_request |
|
4380 || m_state == eap_type_gsmsim_state_analyses_reauthentication_request |
|
4381 || m_state == eap_type_gsmsim_state_success |
|
4382 || m_state == eap_type_gsmsim_state_failure |
|
4383 ) |
|
4384 #endif //#if defined(USE_EAP_GSMSIM_VERIFY_STATES) |
|
4385 { |
|
4386 // This could be first or retransmission request. |
|
4387 |
|
4388 // Checks the payloads existence. |
|
4389 if (p_gsmsim_payloads->check_payloads( |
|
4390 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_mt |
|
4391 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_s |
|
4392 gsmsim_payloads_c::eap_gsmsim_payload_status_optional, // MAC |
|
4393 gsmsim_payloads_c::eap_gsmsim_payload_status_optional, // ENCR_DATA |
|
4394 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // IDENTITY |
|
4395 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // padding |
|
4396 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // n_RANDs |
|
4397 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // PERMANENT_ID_REQ |
|
4398 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // FULLAUTH_ID_REQ |
|
4399 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // ANY_ID_REQ |
|
4400 gsmsim_payloads_c::eap_gsmsim_payload_status_optional, // IV |
|
4401 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_PSEUDONYM |
|
4402 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_REAUTH_ID |
|
4403 gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // NOTIFICATION |
|
4404 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // VERSION_LIST |
|
4405 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // SELECTED_VERSION |
|
4406 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER |
|
4407 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER_TOO_SMALL |
|
4408 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // CLIENT_ERROR_CODE |
|
4409 gsmsim_payloads_c::eap_gsmsim_payload_status_optional // RESULT_IND |
|
4410 ) == true |
|
4411 ) |
|
4412 { |
|
4413 // NOTE, this message is unauthenticated. Anybody could sent this message. |
|
4414 |
|
4415 // We store the received notification code. This will be handled after session timeouts. |
|
4416 m_gsmsim_notification_code = |
|
4417 static_cast<eap_gsmsim_notification_codes_e>( |
|
4418 p_gsmsim_payloads->get_NOTIFICATION()->get_original_header()->get_reserved()); |
|
4419 |
|
4420 save_current_state(); |
|
4421 |
|
4422 m_last_eap_identifier = received_gsmsim->get_identifier(); |
|
4423 |
|
4424 EAP_TRACE_DEBUG( |
|
4425 m_am_tools, |
|
4426 TRACE_FLAGS_DEFAULT, |
|
4427 (EAPL("eap_type_gsmsim_c::handle_gsmsim_notification_request_message(0x%08x), ") |
|
4428 EAPL("notification_code = 0x%04x, F bit %d, P bit %d, state %d=%s.\n"), |
|
4429 this, |
|
4430 m_gsmsim_notification_code, |
|
4431 get_gsmsim_notification_code_F_bit(m_gsmsim_notification_code), |
|
4432 get_gsmsim_notification_code_P_bit(m_gsmsim_notification_code), |
|
4433 m_state, |
|
4434 get_state_string())); |
|
4435 |
|
4436 if (m_authentication_type == GSMSIM_AUTHENTICATION_TYPE_REAUTHENTICATION) |
|
4437 { |
|
4438 status = handle_gsmsim_notification_request_message_reauthentication( |
|
4439 receive_network_id, |
|
4440 received_gsmsim, |
|
4441 gsmsim_packet_length, |
|
4442 p_gsmsim_payloads); |
|
4443 if (status != eap_status_ok) |
|
4444 { |
|
4445 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4446 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4447 } |
|
4448 } |
|
4449 else |
|
4450 { |
|
4451 status = handle_gsmsim_notification_request_message_full_authentication( |
|
4452 receive_network_id, |
|
4453 received_gsmsim, |
|
4454 gsmsim_packet_length, |
|
4455 p_gsmsim_payloads); |
|
4456 if (status != eap_status_ok) |
|
4457 { |
|
4458 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4459 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4460 } |
|
4461 } |
|
4462 } |
|
4463 else |
|
4464 { |
|
4465 // Not correct GSMSIM-payloads are included. |
|
4466 EAP_TRACE_ERROR( |
|
4467 m_am_tools, |
|
4468 TRACE_FLAGS_GSMSIM_ERROR, |
|
4469 (EAPL("ERROR: eap_type_gsmsim_c::handle_gsmsim_notification_request_message(1): ") |
|
4470 EAPL("Not correct GSMSIM-payloads are included in eap_type_gsmsim_state_variable_e %d=%s.\n"), |
|
4471 m_state, |
|
4472 get_state_string())); |
|
4473 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4474 return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); |
|
4475 } |
|
4476 } |
|
4477 else |
|
4478 { |
|
4479 // Wrong message in this state. |
|
4480 EAP_TRACE_ERROR( |
|
4481 m_am_tools, |
|
4482 TRACE_FLAGS_GSMSIM_ERROR, |
|
4483 (EAPL("ERROR: eap_type_gsmsim_c::handle_gsmsim_notification_request_message(): ") |
|
4484 EAPL("Wrong message %d=%s in eap_type_gsmsim_state_variable_e %d=%s.\n"), |
|
4485 received_gsmsim->get_subtype(), |
|
4486 received_gsmsim->get_subtype_string(), |
|
4487 m_state, |
|
4488 get_state_string())); |
|
4489 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4490 return EAP_STATUS_RETURN(m_am_tools, eap_status_authentication_failure); |
|
4491 } |
|
4492 |
|
4493 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4494 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4495 } |
|
4496 |
|
4497 |
|
4498 //-------------------------------------------------- |
|
4499 |
|
4500 // |
|
4501 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::handle_challenge_request_message( |
|
4502 const eap_am_network_id_c * const /* receive_network_id */, |
|
4503 gsmsim_header_c * const received_gsmsim, |
|
4504 const u32_t gsmsim_packet_length, |
|
4505 gsmsim_payloads_c * const p_gsmsim_payloads) |
|
4506 { |
|
4507 eap_status_e status = eap_status_process_general_error; |
|
4508 |
|
4509 if (m_state == eap_type_gsmsim_state_waiting_for_challenge_request |
|
4510 || (m_state == eap_type_gsmsim_state_waiting_for_success && m_use_result_indication == false) |
|
4511 || (m_state == eap_type_gsmsim_state_waiting_for_notification_request_success && m_use_result_indication == true)) |
|
4512 { |
|
4513 // This could be first or retransmission request. |
|
4514 |
|
4515 // Checks the payloads existence. |
|
4516 if (p_gsmsim_payloads->check_payloads( |
|
4517 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_mt |
|
4518 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_s |
|
4519 gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // MAC |
|
4520 gsmsim_payloads_c::eap_gsmsim_payload_status_optional, // ENCR_DATA |
|
4521 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // IDENTITY |
|
4522 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // padding |
|
4523 gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // n_RANDs |
|
4524 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // PERMANENT_ID_REQ |
|
4525 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // FULLAUTH_ID_REQ |
|
4526 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // ANY_ID_REQ |
|
4527 gsmsim_payloads_c::eap_gsmsim_payload_status_optional, // IV |
|
4528 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_PSEUDONYM |
|
4529 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_REAUTH_ID |
|
4530 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NOTIFICATION |
|
4531 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // VERSION_LIST |
|
4532 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // SELECTED_VERSION |
|
4533 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER |
|
4534 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER_TOO_SMALL |
|
4535 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // CLIENT_ERROR_CODE |
|
4536 gsmsim_payloads_c::eap_gsmsim_payload_status_optional // RESULT_IND |
|
4537 ) == true |
|
4538 ) |
|
4539 { |
|
4540 if (p_gsmsim_payloads->get_RESULT_IND()->get_payload_included() == true) |
|
4541 { |
|
4542 m_use_result_indication = m_allow_use_result_indication; |
|
4543 } |
|
4544 else |
|
4545 { |
|
4546 m_use_result_indication = false; |
|
4547 } |
|
4548 |
|
4549 if (p_gsmsim_payloads->get_IV()->get_payload_included() == true |
|
4550 || p_gsmsim_payloads->get_ENCR_DATA()->get_payload_included() == true) |
|
4551 { |
|
4552 if (p_gsmsim_payloads->get_IV()->get_payload_included() == true |
|
4553 && p_gsmsim_payloads->get_ENCR_DATA()->get_payload_included() == true) |
|
4554 { |
|
4555 // OK |
|
4556 } |
|
4557 else |
|
4558 { |
|
4559 // All of these must be included |
|
4560 // or none of these must be included. |
|
4561 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); |
|
4562 } |
|
4563 } |
|
4564 |
|
4565 // The whole EAP packet must copied. |
|
4566 // The MAC is checked later after n*Kc and n*SRES is get from SIM. |
|
4567 status = m_saved_EAP_packet.set_copy_of_buffer( |
|
4568 received_gsmsim->get_header_buffer(gsmsim_packet_length), |
|
4569 gsmsim_packet_length); |
|
4570 if (status != eap_status_ok) |
|
4571 { |
|
4572 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4573 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4574 } |
|
4575 |
|
4576 m_last_eap_identifier = received_gsmsim->get_identifier(); |
|
4577 |
|
4578 save_current_state(); |
|
4579 set_state(eap_type_gsmsim_state_analyses_challenge_request); |
|
4580 |
|
4581 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
4582 |
|
4583 eap_variable_data_c n_kc(m_am_tools); |
|
4584 eap_variable_data_c n_sres(m_am_tools); |
|
4585 |
|
4586 status = query_SIM_kc_sres( |
|
4587 p_gsmsim_payloads->get_n_RANDs()->get_payload_buffer(), |
|
4588 &n_kc, |
|
4589 &n_sres); |
|
4590 if (status == eap_status_pending_request) |
|
4591 { |
|
4592 // Request will be completed later using complete_SIM_kc_sres() function. |
|
4593 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4594 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
4595 } |
|
4596 else if (status == eap_status_completed_request) |
|
4597 { |
|
4598 // Request was already completed by AM using complete_SIM_kc_sres() function. |
|
4599 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4600 return EAP_STATUS_RETURN(m_am_tools, eap_status_ok); |
|
4601 } |
|
4602 else if (status == eap_status_success) |
|
4603 { |
|
4604 // eap_status_success means the authentication was successful. |
|
4605 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4606 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4607 } |
|
4608 else if (status == eap_status_ok) |
|
4609 { |
|
4610 // The query_SIM_kc_sres() function call is synchronous. |
|
4611 // We must call process_SIM_kc_sres(). |
|
4612 } |
|
4613 else |
|
4614 { |
|
4615 // This is an error case. |
|
4616 restore_saved_previous_state(); |
|
4617 |
|
4618 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4619 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4620 } |
|
4621 |
|
4622 // eap_status_ok status value means n_kc and n_sres were read but not processed. |
|
4623 // Next we must call process_SIM_kc_sres(). |
|
4624 |
|
4625 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
4626 |
|
4627 status = process_SIM_kc_sres( |
|
4628 p_gsmsim_payloads->get_n_RANDs()->get_payload_buffer(), |
|
4629 &n_kc, |
|
4630 &n_sres); |
|
4631 |
|
4632 if (status != eap_status_ok |
|
4633 && status != eap_status_success) |
|
4634 { |
|
4635 (void) initialize_error_message(status); |
|
4636 |
|
4637 restore_saved_previous_state(); |
|
4638 } |
|
4639 |
|
4640 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4641 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4642 } |
|
4643 else |
|
4644 { |
|
4645 // Not correct GSMSIM-payloads are included. |
|
4646 EAP_TRACE_ERROR( |
|
4647 m_am_tools, |
|
4648 TRACE_FLAGS_GSMSIM_ERROR, |
|
4649 (EAPL("ERROR: eap_type_gsmsim_c::handle_challenge_request_message(6): ") |
|
4650 EAPL("Not correct GSMSIM-payloads are included in eap_type_gsmsim_state_variable_e %d=%s.\n"), |
|
4651 m_state, |
|
4652 get_state_string())); |
|
4653 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4654 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
4655 } |
|
4656 } |
|
4657 else if (m_state == eap_type_gsmsim_state_pending_kc_sres_query) |
|
4658 { |
|
4659 // This is re-transmitted EAP-Request/SIM/Challenge. |
|
4660 // We dischard it quietly. |
|
4661 EAP_TRACE_ERROR( |
|
4662 m_am_tools, |
|
4663 TRACE_FLAGS_DEFAULT, |
|
4664 (EAPL("WARNING: eap_type_gsmsim_c::handle_challenge_request_message(): ") |
|
4665 EAPL("Re-transmitted message %d=%s dropped in eap_type_gsmsim_state_variable_e %d=%s.\n"), |
|
4666 received_gsmsim->get_subtype(), |
|
4667 received_gsmsim->get_subtype_string(), |
|
4668 m_state, |
|
4669 get_state_string())); |
|
4670 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4671 return EAP_STATUS_RETURN(m_am_tools, eap_status_drop_packet_quietly); |
|
4672 } |
|
4673 else |
|
4674 { |
|
4675 // Wrong message in this state. |
|
4676 EAP_TRACE_ERROR( |
|
4677 m_am_tools, |
|
4678 TRACE_FLAGS_GSMSIM_ERROR, |
|
4679 (EAPL("ERROR: eap_type_gsmsim_c::handle_challenge_request_message(): ") |
|
4680 EAPL("Wrong message %d=%s in eap_type_gsmsim_state_variable_e %d=%s.\n"), |
|
4681 received_gsmsim->get_subtype(), |
|
4682 received_gsmsim->get_subtype_string(), |
|
4683 m_state, |
|
4684 get_state_string())); |
|
4685 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4686 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
4687 } |
|
4688 } |
|
4689 |
|
4690 //-------------------------------------------------- |
|
4691 |
|
4692 // |
|
4693 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::handle_reauthentication_request_message( |
|
4694 const eap_am_network_id_c * const receive_network_id, |
|
4695 gsmsim_header_c * const received_gsmsim, |
|
4696 const u32_t gsmsim_packet_length, |
|
4697 gsmsim_payloads_c * const p_gsmsim_payloads) |
|
4698 { |
|
4699 eap_status_e status = eap_status_process_general_error; |
|
4700 |
|
4701 if (m_state == eap_type_gsmsim_state_waiting_for_reauth_request |
|
4702 || (m_state == eap_type_gsmsim_state_waiting_for_success && m_use_result_indication == false) |
|
4703 || (m_state == eap_type_gsmsim_state_waiting_for_notification_request_success && m_use_result_indication == true)) |
|
4704 { |
|
4705 // This could be first or retransmission request. |
|
4706 |
|
4707 // Checks the payloads existence. |
|
4708 if (p_gsmsim_payloads->check_payloads( |
|
4709 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_mt |
|
4710 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // nonce_s |
|
4711 gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // MAC |
|
4712 gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // ENCR_DATA |
|
4713 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // IDENTITY |
|
4714 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // padding |
|
4715 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // n_RANDs |
|
4716 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // PERMANENT_ID_REQ |
|
4717 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // FULLAUTH_ID_REQ |
|
4718 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // ANY_ID_REQ |
|
4719 gsmsim_payloads_c::eap_gsmsim_payload_status_must_be, // IV |
|
4720 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_PSEUDONYM |
|
4721 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NEXT_REAUTH_ID |
|
4722 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // NOTIFICATION |
|
4723 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // VERSION_LIST |
|
4724 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // SELECTED_VERSION |
|
4725 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER |
|
4726 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // COUNTER_TOO_SMALL |
|
4727 gsmsim_payloads_c::eap_gsmsim_payload_status_must_not_be, // CLIENT_ERROR_CODE |
|
4728 gsmsim_payloads_c::eap_gsmsim_payload_status_optional // RESULT_IND |
|
4729 ) == true |
|
4730 ) |
|
4731 { |
|
4732 |
|
4733 m_last_eap_identifier = received_gsmsim->get_identifier(); |
|
4734 |
|
4735 save_current_state(); |
|
4736 set_state(eap_type_gsmsim_state_analyses_reauthentication_request); |
|
4737 |
|
4738 // - - - - - - - - - - - - - - - - - - - - - - - - |
|
4739 |
|
4740 eap_variable_data_c orig_XKEY(m_am_tools); |
|
4741 eap_variable_data_c orig_K_aut(m_am_tools); |
|
4742 eap_variable_data_c orig_K_encr(m_am_tools); |
|
4743 u32_t reauth_counter = 0u; |
|
4744 // In order to use re-authentication, the client and the server need to |
|
4745 // store the following values: original XKEY, K_aut, K_encr, latest |
|
4746 // counter value and the next re-authentication identity. |
|
4747 status = m_am_type_gsmsim->query_reauth_parameters( |
|
4748 &orig_XKEY, |
|
4749 &orig_K_aut, |
|
4750 &orig_K_encr, |
|
4751 &reauth_counter); |
|
4752 if (status != eap_status_ok) |
|
4753 { |
|
4754 restore_saved_previous_state(); |
|
4755 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4756 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4757 } |
|
4758 |
|
4759 EAP_TRACE_DEBUG( |
|
4760 m_am_tools, |
|
4761 TRACE_FLAGS_DEFAULT, |
|
4762 (EAPL("eap_type_gsmsim_c::handle_reauthentication_request_message(): %s, m_saved_reauth_counter %d.\n"), |
|
4763 (m_is_client == true ? "client": "server"), |
|
4764 reauth_counter)); |
|
4765 |
|
4766 status = check_message_authentication_code( |
|
4767 &orig_K_aut, |
|
4768 p_gsmsim_payloads, |
|
4769 received_gsmsim, |
|
4770 gsmsim_packet_length); |
|
4771 if (status != eap_status_ok) |
|
4772 { |
|
4773 (void) initialize_error_message(status); |
|
4774 |
|
4775 restore_saved_previous_state(); |
|
4776 |
|
4777 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4778 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4779 } |
|
4780 |
|
4781 if (p_gsmsim_payloads->get_RESULT_IND()->get_payload_included() == true) |
|
4782 { |
|
4783 m_use_result_indication = m_allow_use_result_indication; |
|
4784 } |
|
4785 else |
|
4786 { |
|
4787 m_use_result_indication = false; |
|
4788 } |
|
4789 |
|
4790 // Decrypt and parse encrypted payload. |
|
4791 if (p_gsmsim_payloads->get_IV()->get_payload_included() == true |
|
4792 || p_gsmsim_payloads->get_ENCR_DATA()->get_payload_included() == true) |
|
4793 { |
|
4794 if (p_gsmsim_payloads->get_IV()->get_payload_included() == true |
|
4795 && p_gsmsim_payloads->get_ENCR_DATA()->get_payload_included() == true |
|
4796 && p_gsmsim_payloads->get_MAC()->get_payload_included() == true) |
|
4797 { |
|
4798 gsmsim_payloads_c * const l_gsmsim_payloads = new gsmsim_payloads_c(m_am_tools); |
|
4799 eap_automatic_variable_c<gsmsim_payloads_c> l_gsmsim_payloads_automatic(m_am_tools, l_gsmsim_payloads); |
|
4800 |
|
4801 if (l_gsmsim_payloads == 0 |
|
4802 || l_gsmsim_payloads->get_is_valid() == false) |
|
4803 { |
|
4804 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4805 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
4806 } |
|
4807 |
|
4808 bool include_at_counter_too_small = false; |
|
4809 |
|
4810 status = decrypt_DATA_payload( |
|
4811 p_gsmsim_payloads, |
|
4812 &orig_K_encr); |
|
4813 if (status != eap_status_ok) |
|
4814 { |
|
4815 restore_saved_previous_state(); |
|
4816 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4817 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4818 } |
|
4819 |
|
4820 u32_t state_payload_buffer_length = p_gsmsim_payloads->get_ENCR_DATA()->get_data_length(); |
|
4821 const gsmsim_payload_AT_header_c gp_data_payload( |
|
4822 m_am_tools, |
|
4823 p_gsmsim_payloads->get_ENCR_DATA()->get_data(state_payload_buffer_length), |
|
4824 state_payload_buffer_length); |
|
4825 |
|
4826 status = parse_gsmsim_payload( |
|
4827 &gp_data_payload, |
|
4828 &state_payload_buffer_length, |
|
4829 l_gsmsim_payloads, |
|
4830 received_gsmsim->get_subtype()); |
|
4831 if (status != eap_status_ok) |
|
4832 { |
|
4833 restore_saved_previous_state(); |
|
4834 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4835 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4836 } |
|
4837 |
|
4838 |
|
4839 if (l_gsmsim_payloads->get_COUNTER()->get_payload_included() == false |
|
4840 || l_gsmsim_payloads->get_NONCE_S()->get_payload_included() == false) |
|
4841 { |
|
4842 restore_saved_previous_state(); |
|
4843 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4844 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); |
|
4845 } |
|
4846 |
|
4847 u32_t counter = l_gsmsim_payloads->get_COUNTER()->get_original_header()->get_reserved(); |
|
4848 |
|
4849 if (m_gsmsim_test_version == true |
|
4850 && m_fail_reauthentication_counter_check == true) |
|
4851 { |
|
4852 --counter; |
|
4853 } |
|
4854 |
|
4855 if (m_saved_previous_state == eap_type_gsmsim_state_waiting_for_reauth_request) |
|
4856 { |
|
4857 if (counter < reauth_counter) |
|
4858 { |
|
4859 // When the client detects that the |
|
4860 // counter value is not fresh, it includes the AT_COUNTER_TOO_SMALL |
|
4861 // attribute in EAP-Response/SIM/Re-authentication. This attribute |
|
4862 // doesn't contain any data but it is a request for the server to |
|
4863 // initiate full authentication. In this case, the client MUST ignore |
|
4864 // the contents of the server's AT_NEXT_REAUTH_ID attribute. |
|
4865 include_at_counter_too_small = true; |
|
4866 l_gsmsim_payloads->get_NEXT_REAUTH_ID()->reset(); |
|
4867 } |
|
4868 } |
|
4869 else if (m_saved_previous_state == eap_type_gsmsim_state_waiting_for_success |
|
4870 || m_state == eap_type_gsmsim_state_waiting_for_notification_request_success) |
|
4871 { |
|
4872 // This is retransmission request. |
|
4873 if (counter+1ul < reauth_counter) |
|
4874 { |
|
4875 // When the client detects that the |
|
4876 // counter value is not fresh, it includes the AT_COUNTER_TOO_SMALL |
|
4877 // attribute in EAP-Response/SIM/Re-authentication. This attribute |
|
4878 // doesn't contain any data but it is a request for the server to |
|
4879 // initiate full authentication. In this case, the client MUST ignore |
|
4880 // the contents of the server's AT_NEXT_REAUTH_ID attribute. |
|
4881 include_at_counter_too_small = true; |
|
4882 l_gsmsim_payloads->get_NEXT_REAUTH_ID()->reset(); |
|
4883 } |
|
4884 } |
|
4885 |
|
4886 if (l_gsmsim_payloads->get_NEXT_REAUTH_ID()->get_payload_included() == true) |
|
4887 { |
|
4888 // Save next re-authentication identity. |
|
4889 // GSMSIM AM could store pseudonym to favourite place. |
|
4890 status = m_am_type_gsmsim->store_reauthentication_id( |
|
4891 &m_send_network_id, |
|
4892 l_gsmsim_payloads->get_NEXT_REAUTH_ID()->get_payload_buffer()); |
|
4893 if (status != eap_status_ok) |
|
4894 { |
|
4895 restore_saved_previous_state(); |
|
4896 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4897 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4898 } |
|
4899 } |
|
4900 else |
|
4901 { |
|
4902 // GSMSIM AM should remove re-authentication identity from favourite place. |
|
4903 |
|
4904 EAP_TRACE_DEBUG( |
|
4905 m_am_tools, |
|
4906 TRACE_FLAGS_DEFAULT, |
|
4907 (EAPL("eap_type_gsmsim_c::handle_reauthentication_request_message(0x%08x): Resets re-authentication identity from database.\n"), |
|
4908 this)); |
|
4909 |
|
4910 status = m_am_type_gsmsim->store_reauthentication_id( |
|
4911 &m_send_network_id, |
|
4912 0); |
|
4913 if (status != eap_status_ok) |
|
4914 { |
|
4915 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4916 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4917 } |
|
4918 |
|
4919 m_reauthentication_identity.reset(); |
|
4920 } |
|
4921 |
|
4922 status = m_nonce_s.set_copy_of_buffer( |
|
4923 l_gsmsim_payloads->get_NONCE_S()->get_payload_buffer()); |
|
4924 if (status != eap_status_ok) |
|
4925 { |
|
4926 restore_saved_previous_state(); |
|
4927 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4928 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4929 } |
|
4930 |
|
4931 status = send_reauthentication_response_message( |
|
4932 &orig_XKEY, |
|
4933 &orig_K_aut, |
|
4934 &orig_K_encr, |
|
4935 &m_NAI, |
|
4936 l_gsmsim_payloads->get_NONCE_S()->get_payload_buffer(), |
|
4937 static_cast<u16_t>(counter), |
|
4938 received_gsmsim->get_identifier(), |
|
4939 include_at_counter_too_small); |
|
4940 if (status != eap_status_ok) |
|
4941 { |
|
4942 restore_saved_previous_state(); |
|
4943 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4944 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4945 } |
|
4946 |
|
4947 // OK, server re-authenticates correcly. |
|
4948 |
|
4949 if (m_use_result_indication == false |
|
4950 && m_saved_previous_state == eap_type_gsmsim_state_waiting_for_reauth_request) |
|
4951 { |
|
4952 // Re-authentication counter is increased only on first time. |
|
4953 // In order to use re-authentication, the client and the server need to |
|
4954 // update re-authentication counter value. |
|
4955 status = m_am_type_gsmsim->increase_reauth_counter(); |
|
4956 if (status != eap_status_ok) |
|
4957 { |
|
4958 restore_saved_previous_state(); |
|
4959 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4960 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4961 } |
|
4962 } |
|
4963 |
|
4964 if (include_at_counter_too_small == true) |
|
4965 { |
|
4966 // Re-authentication failed. |
|
4967 // We will expect full authentication. |
|
4968 set_state(eap_type_gsmsim_state_waiting_for_start_request); |
|
4969 status = eap_status_ok; |
|
4970 } |
|
4971 else |
|
4972 { |
|
4973 // Authentication was successful. |
|
4974 if (m_use_result_indication == true) |
|
4975 { |
|
4976 // This version waits the result indication. |
|
4977 set_state(eap_type_gsmsim_state_waiting_for_notification_request_success); |
|
4978 status = eap_status_ok; |
|
4979 |
|
4980 EAP_TRACE_DEBUG( |
|
4981 m_am_tools, |
|
4982 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
4983 (EAPL("EAP_type_GSMSIM: %s, re-authentication OK, waits result indication\n"), |
|
4984 (m_is_client == true) ? "client": "server")); |
|
4985 } |
|
4986 else if (m_wait_eap_success_packet == false) |
|
4987 { |
|
4988 // This version does not wait EAP-Success message. |
|
4989 status = finish_successful_authentication( |
|
4990 receive_network_id); |
|
4991 if (status != eap_status_ok) |
|
4992 { |
|
4993 restore_saved_previous_state(); |
|
4994 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
4995 return EAP_STATUS_RETURN(m_am_tools, status); |
|
4996 } |
|
4997 } |
|
4998 else |
|
4999 { |
|
5000 // This version waits the EAP-Success message. |
|
5001 set_state(eap_type_gsmsim_state_waiting_for_success); |
|
5002 status = eap_status_ok; |
|
5003 |
|
5004 EAP_TRACE_DEBUG( |
|
5005 m_am_tools, |
|
5006 TRACE_FLAGS_DEFAULT|TRACE_TEST_VECTORS, |
|
5007 (EAPL("EAP_type_GSMSIM: %s, re-authentication OK, waits EAP-Success\n"), |
|
5008 (m_is_client == true) ? "client": "server")); |
|
5009 } |
|
5010 } |
|
5011 |
|
5012 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5013 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5014 } |
|
5015 else |
|
5016 { |
|
5017 // All of these must be included |
|
5018 // or none of these must be included. |
|
5019 restore_saved_previous_state(); |
|
5020 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_payload); |
|
5021 } |
|
5022 } |
|
5023 else |
|
5024 { |
|
5025 // Not correct GSMSIM-payloads are included. |
|
5026 restore_saved_previous_state(); |
|
5027 EAP_TRACE_ERROR( |
|
5028 m_am_tools, |
|
5029 TRACE_FLAGS_GSMSIM_ERROR, |
|
5030 (EAPL("ERROR: eap_type_gsmsim_c::handle_reauthentication_request_message(6): ") |
|
5031 EAPL("Not correct GSMSIM-payloads are included in eap_type_gsmsim_state_variable_e %d=%s.\n"), |
|
5032 m_state, |
|
5033 get_state_string())); |
|
5034 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5035 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
5036 } |
|
5037 } |
|
5038 else |
|
5039 { |
|
5040 // Not correct GSMSIM-payloads are included. |
|
5041 EAP_TRACE_ERROR( |
|
5042 m_am_tools, |
|
5043 TRACE_FLAGS_GSMSIM_ERROR, |
|
5044 (EAPL("ERROR: eap_type_gsmsim_c::handle_reauthentication_request_message(6): ") |
|
5045 EAPL("Not correct GSMSIM-payloads are included in eap_type_gsmsim_state_variable_e %d=%s.\n"), |
|
5046 m_state, |
|
5047 get_state_string())); |
|
5048 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5049 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
5050 } |
|
5051 } |
|
5052 else |
|
5053 { |
|
5054 // Wrong message in this state. |
|
5055 EAP_TRACE_ERROR( |
|
5056 m_am_tools, |
|
5057 TRACE_FLAGS_GSMSIM_ERROR, |
|
5058 (EAPL("ERROR: eap_type_gsmsim_c::handle_reauthentication_request_message(): ") |
|
5059 EAPL("Wrong message %d=%s in eap_type_gsmsim_state_variable_e %d=%s.\n"), |
|
5060 received_gsmsim->get_subtype(), |
|
5061 received_gsmsim->get_subtype_string(), |
|
5062 m_state, |
|
5063 get_state_string())); |
|
5064 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5065 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
5066 } |
|
5067 } |
|
5068 |
|
5069 //-------------------------------------------------- |
|
5070 |
|
5071 // |
|
5072 eap_status_e eap_type_gsmsim_c::handle_eap_identity_query( |
|
5073 const eap_am_network_id_c * const send_network_id, |
|
5074 eap_variable_data_c * const p_identity, |
|
5075 const u8_t eap_identifier, |
|
5076 const eap_variable_data_c * const IMSI, |
|
5077 const eap_variable_data_c * const pseudonym, |
|
5078 const eap_variable_data_c * const reauthentication_identity, |
|
5079 const eap_variable_data_c * const automatic_realm, |
|
5080 const u32_t length_of_mnc, |
|
5081 const bool must_be_synchronous) |
|
5082 { |
|
5083 const eap_variable_data_c *current_identity = 0; |
|
5084 eap_variable_data_c manual_identity(m_am_tools); |
|
5085 bool IMSI_is_used = false; |
|
5086 bool reauth_id_is_used = false; |
|
5087 eap_status_e status = eap_status_process_general_error; |
|
5088 |
|
5089 if (m_state != eap_type_gsmsim_state_pending_identity_query) |
|
5090 { |
|
5091 // Authentication is state is wrong. Cannot continue. |
|
5092 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5093 return EAP_STATUS_RETURN(m_am_tools, eap_status_wrong_gsmsim_state); |
|
5094 } |
|
5095 |
|
5096 if (must_be_synchronous == true |
|
5097 && p_identity == 0) |
|
5098 { |
|
5099 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5100 return EAP_STATUS_RETURN(m_am_tools, eap_status_process_general_error); |
|
5101 } |
|
5102 |
|
5103 if (IMSI == 0 |
|
5104 || IMSI->get_is_valid_data() == false |
|
5105 || IMSI->get_data_length() < EAP_TYPE_GSMSIM_MINIMUM_IMSI_LENGTH) |
|
5106 { |
|
5107 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5108 return EAP_STATUS_RETURN(m_am_tools, eap_status_illegal_eap_identity); |
|
5109 } |
|
5110 |
|
5111 |
|
5112 // We must save queried re-authentication and pseudonym identity. |
|
5113 if (reauthentication_identity != 0 |
|
5114 && reauthentication_identity->get_is_valid_data() == true) |
|
5115 { |
|
5116 status = m_reauthentication_identity.set_copy_of_buffer(reauthentication_identity); |
|
5117 if (status != eap_status_ok) |
|
5118 { |
|
5119 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5120 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5121 } |
|
5122 } |
|
5123 |
|
5124 if (pseudonym != 0 |
|
5125 && pseudonym->get_is_valid_data() == true) |
|
5126 { |
|
5127 status = m_pseudonym.set_copy_of_buffer(pseudonym); |
|
5128 if (status != eap_status_ok) |
|
5129 { |
|
5130 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5131 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5132 } |
|
5133 } |
|
5134 |
|
5135 |
|
5136 if (m_use_manual_username == true |
|
5137 && m_manual_username.get_is_valid_data() == true |
|
5138 && m_use_manual_realm == true |
|
5139 && m_manual_realm.get_is_valid_data() == true) |
|
5140 { |
|
5141 // Here manual username could be zero or more bytes in length. |
|
5142 EAP_TRACE_DEBUG( |
|
5143 m_am_tools, |
|
5144 TRACE_FLAGS_DEFAULT, |
|
5145 (EAPL("eap_type_gsmsim_c::handle_eap_identity_query(): Client sends manual username and realm.\n"))); |
|
5146 |
|
5147 status = manual_identity.set_copy_of_buffer(&m_manual_username); |
|
5148 if (status != eap_status_ok) |
|
5149 { |
|
5150 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5151 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5152 } |
|
5153 |
|
5154 current_identity = &manual_identity; |
|
5155 IMSI_is_used = false; |
|
5156 } |
|
5157 else if (m_use_manual_username == true |
|
5158 && m_manual_username.get_is_valid_data() == true |
|
5159 && m_use_manual_realm == false) |
|
5160 { |
|
5161 // We will send manual username with automatic realm. |
|
5162 EAP_TRACE_DEBUG( |
|
5163 m_am_tools, |
|
5164 TRACE_FLAGS_DEFAULT, |
|
5165 (EAPL("eap_type_gsmsim_c::handle_eap_identity_query(): Client sends manual username and automatic realm.\n"))); |
|
5166 |
|
5167 status = manual_identity.set_copy_of_buffer(&m_manual_username); |
|
5168 if (status != eap_status_ok) |
|
5169 { |
|
5170 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5171 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5172 } |
|
5173 |
|
5174 current_identity = &manual_identity; |
|
5175 IMSI_is_used = false; |
|
5176 } |
|
5177 else if (reauthentication_identity != 0 |
|
5178 && reauthentication_identity->get_is_valid_data() == true) |
|
5179 { |
|
5180 EAP_TRACE_DEBUG( |
|
5181 m_am_tools, |
|
5182 TRACE_FLAGS_DEFAULT, |
|
5183 (EAPL("eap_type_gsmsim_c::handle_eap_identity_query(): Client sends re-authentication identity.\n"))); |
|
5184 |
|
5185 current_identity = reauthentication_identity; |
|
5186 IMSI_is_used = false; |
|
5187 reauth_id_is_used = true; |
|
5188 |
|
5189 status = m_reauthentication_identity.set_copy_of_buffer(reauthentication_identity); |
|
5190 if (status != eap_status_ok) |
|
5191 { |
|
5192 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5193 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5194 } |
|
5195 } |
|
5196 else if (pseudonym != 0 |
|
5197 && pseudonym->get_is_valid_data() == true) |
|
5198 { |
|
5199 EAP_TRACE_DEBUG( |
|
5200 m_am_tools, |
|
5201 TRACE_FLAGS_DEFAULT, |
|
5202 (EAPL("eap_type_gsmsim_c::handle_eap_identity_query(): Client sends pseudonym username.\n"))); |
|
5203 |
|
5204 current_identity = pseudonym; |
|
5205 IMSI_is_used = false; |
|
5206 |
|
5207 status = m_pseudonym.set_copy_of_buffer(pseudonym); |
|
5208 if (status != eap_status_ok) |
|
5209 { |
|
5210 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5211 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5212 } |
|
5213 } |
|
5214 else if (m_use_random_identity_on_eap_identity_response == true) |
|
5215 { |
|
5216 // Generate random username. |
|
5217 EAP_TRACE_DEBUG( |
|
5218 m_am_tools, |
|
5219 TRACE_FLAGS_DEFAULT, |
|
5220 (EAPL("eap_type_gsmsim_c::handle_eap_identity_query(): Client sends random username.\n"))); |
|
5221 |
|
5222 const u32_t EAP_TLS_PEAP_RANDOM_IDENTITY_LENGTH = 16; |
|
5223 eap_variable_data_c random_username(m_am_tools); |
|
5224 eap_variable_data_c random_bytes(m_am_tools); |
|
5225 |
|
5226 status = random_bytes.init(EAP_TLS_PEAP_RANDOM_IDENTITY_LENGTH); |
|
5227 if (status != eap_status_ok) |
|
5228 { |
|
5229 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5230 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5231 } |
|
5232 random_bytes.set_is_valid(); |
|
5233 random_bytes.set_data_length(EAP_TLS_PEAP_RANDOM_IDENTITY_LENGTH); |
|
5234 |
|
5235 status = m_am_tools->get_crypto()->get_rand_bytes( |
|
5236 random_bytes.get_data(), |
|
5237 random_bytes.get_data_length()); |
|
5238 if (status != eap_status_ok) |
|
5239 { |
|
5240 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5241 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5242 } |
|
5243 |
|
5244 // Change first byte to 'r' to make it different than the default IMSI prefix '1'. |
|
5245 // This will cause the first identity char 'S' after ascii armor conversion. |
|
5246 *random_bytes.get_data(1ul) = static_cast<u8_t>('r'); |
|
5247 |
|
5248 const u32_t EAP_GSMSIM_RANDOM_IDENTITY_BUFFER_LENGTH |
|
5249 = 3ul+(EAP_TLS_PEAP_RANDOM_IDENTITY_LENGTH+1u)*4u/3u; |
|
5250 |
|
5251 status = random_username.init(EAP_GSMSIM_RANDOM_IDENTITY_BUFFER_LENGTH); |
|
5252 if (status != eap_status_ok) |
|
5253 { |
|
5254 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5255 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5256 } |
|
5257 random_username.set_is_valid(); |
|
5258 random_username.set_data_length(EAP_GSMSIM_RANDOM_IDENTITY_BUFFER_LENGTH); |
|
5259 |
|
5260 u32_t random_identity_length = random_username.get_data_length(); |
|
5261 |
|
5262 status = m_am_tools->convert_bytes_to_ascii_armor( |
|
5263 random_bytes.get_data(), |
|
5264 random_bytes.get_data_length(), |
|
5265 random_username.get_data(random_username.get_data_length()), |
|
5266 &random_identity_length); |
|
5267 if (status != eap_status_ok) |
|
5268 { |
|
5269 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5270 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5271 } |
|
5272 random_username.set_data_length(random_identity_length); |
|
5273 |
|
5274 status = manual_identity.set_copy_of_buffer(&random_username); |
|
5275 if (status != eap_status_ok) |
|
5276 { |
|
5277 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5278 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5279 } |
|
5280 |
|
5281 current_identity = &manual_identity; |
|
5282 IMSI_is_used = false; |
|
5283 } |
|
5284 else if (IMSI != 0 |
|
5285 && IMSI->get_is_valid_data() == true |
|
5286 && IMSI->get_data_length() >= EAP_TYPE_GSMSIM_MINIMUM_IMSI_LENGTH) |
|
5287 { |
|
5288 EAP_TRACE_DEBUG( |
|
5289 m_am_tools, |
|
5290 TRACE_FLAGS_DEFAULT, |
|
5291 (EAPL("eap_type_gsmsim_c::handle_eap_identity_query(): Client sends IMSI username.\n"))); |
|
5292 |
|
5293 current_identity = IMSI; |
|
5294 IMSI_is_used = true; |
|
5295 } |
|
5296 |
|
5297 if (current_identity != 0) |
|
5298 { |
|
5299 status = m_IMSI.set_copy_of_buffer(IMSI); |
|
5300 if (status != eap_status_ok) |
|
5301 { |
|
5302 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5303 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5304 } |
|
5305 |
|
5306 status = store_identity(current_identity, IMSI_is_used); |
|
5307 if (status != eap_status_ok) |
|
5308 { |
|
5309 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5310 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5311 } |
|
5312 |
|
5313 EAP_TRACE_DATA_DEBUG(m_am_tools, TRACE_FLAGS_DEFAULT, (EAPL("current_identity"), |
|
5314 current_identity->get_data(), |
|
5315 current_identity->get_data_length())); |
|
5316 |
|
5317 eap_variable_data_c NAI(m_am_tools); |
|
5318 |
|
5319 if (reauth_id_is_used == true) |
|
5320 { |
|
5321 // Re-authentication identity is NAI. |
|
5322 status = NAI.set_copy_of_buffer(current_identity); |
|
5323 if (status != eap_status_ok) |
|
5324 { |
|
5325 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5326 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5327 } |
|
5328 } |
|
5329 else |
|
5330 { |
|
5331 status = generate_nai( |
|
5332 &NAI, |
|
5333 m_use_manual_realm, |
|
5334 get_nai_realm(), |
|
5335 current_identity, |
|
5336 IMSI_is_used, |
|
5337 &m_IMSI, |
|
5338 automatic_realm, |
|
5339 length_of_mnc); |
|
5340 } |
|
5341 |
|
5342 if (status == eap_status_ok) |
|
5343 { |
|
5344 status = m_NAI.set_copy_of_buffer(&NAI); |
|
5345 if (status != eap_status_ok) |
|
5346 { |
|
5347 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5348 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5349 } |
|
5350 |
|
5351 if (must_be_synchronous == false) |
|
5352 { |
|
5353 status = get_type_partner()->complete_eap_identity_query( |
|
5354 send_network_id, |
|
5355 &m_NAI, |
|
5356 eap_identifier); |
|
5357 if (status == eap_status_ok) |
|
5358 { |
|
5359 if (p_identity != 0) |
|
5360 { |
|
5361 status = p_identity->set_copy_of_buffer(&m_NAI); |
|
5362 } |
|
5363 |
|
5364 if (status == eap_status_ok) |
|
5365 { |
|
5366 status = eap_status_completed_request; |
|
5367 } |
|
5368 } |
|
5369 } |
|
5370 else |
|
5371 { |
|
5372 status = p_identity->set_copy_of_buffer(&m_NAI); |
|
5373 } |
|
5374 |
|
5375 if (status == eap_status_ok |
|
5376 || status == eap_status_completed_request) |
|
5377 { |
|
5378 if (m_use_random_identity_on_eap_identity_response == true) |
|
5379 { |
|
5380 m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_NONE; |
|
5381 set_identity_type(GSMSIM_IDENTITY_TYPE_NONE); |
|
5382 set_state(eap_type_gsmsim_state_waiting_for_start_request); |
|
5383 |
|
5384 EAP_TRACE_DEBUG( |
|
5385 m_am_tools, |
|
5386 TRACE_FLAGS_DEFAULT, |
|
5387 (EAPL("eap_type_gsmsim_c::handle_eap_identity_query(0x%08x): Selects none.\n"), |
|
5388 this)); |
|
5389 } |
|
5390 else if (reauthentication_identity != 0 |
|
5391 && reauthentication_identity->get_is_valid_data() == true) |
|
5392 { |
|
5393 m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_REAUTHENTICATION; |
|
5394 set_identity_type(GSMSIM_IDENTITY_TYPE_RE_AUTH_ID); |
|
5395 set_state(eap_type_gsmsim_state_waiting_for_reauth_request); |
|
5396 |
|
5397 EAP_TRACE_DEBUG( |
|
5398 m_am_tools, |
|
5399 TRACE_FLAGS_DEFAULT, |
|
5400 (EAPL("eap_type_gsmsim_c::handle_eap_identity_query(0x%08x): Selects fast re-authentication and re-authentication identity.\n"), |
|
5401 this)); |
|
5402 } |
|
5403 else if (pseudonym != 0 |
|
5404 && pseudonym->get_is_valid_data() == true) |
|
5405 { |
|
5406 m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH; |
|
5407 set_identity_type(GSMSIM_IDENTITY_TYPE_PSEUDONYM_ID); |
|
5408 set_state(eap_type_gsmsim_state_pseydonym_waiting_for_start_request); |
|
5409 |
|
5410 EAP_TRACE_DEBUG( |
|
5411 m_am_tools, |
|
5412 TRACE_FLAGS_DEFAULT, |
|
5413 (EAPL("eap_type_gsmsim_c::handle_eap_identity_query(0x%08x): Selects full authentication and pseudonym identity.\n"), |
|
5414 this)); |
|
5415 } |
|
5416 else |
|
5417 { |
|
5418 if (m_use_manual_username == true) |
|
5419 { |
|
5420 m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_NONE; |
|
5421 set_identity_type(GSMSIM_IDENTITY_TYPE_NONE); |
|
5422 set_state(eap_type_gsmsim_state_waiting_for_start_request); |
|
5423 |
|
5424 EAP_TRACE_DEBUG( |
|
5425 m_am_tools, |
|
5426 TRACE_FLAGS_DEFAULT, |
|
5427 (EAPL("eap_type_gsmsim_c::handle_eap_identity_query(0x%08x): Selects none.\n"), |
|
5428 this)); |
|
5429 } |
|
5430 else |
|
5431 { |
|
5432 m_authentication_type = GSMSIM_AUTHENTICATION_TYPE_FULL_AUTH; |
|
5433 set_identity_type(GSMSIM_IDENTITY_TYPE_IMSI_ID); |
|
5434 set_state(eap_type_gsmsim_state_imsi_waiting_for_start_request); |
|
5435 |
|
5436 EAP_TRACE_DEBUG( |
|
5437 m_am_tools, |
|
5438 TRACE_FLAGS_DEFAULT, |
|
5439 (EAPL("eap_type_gsmsim_c::handle_eap_identity_query(0x%08x): Selects full authentication and IMSI identity.\n"), |
|
5440 this)); |
|
5441 } |
|
5442 } |
|
5443 } |
|
5444 } |
|
5445 } |
|
5446 else |
|
5447 { |
|
5448 status = eap_status_illegal_nai; |
|
5449 } |
|
5450 |
|
5451 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5452 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5453 } |
|
5454 |
|
5455 //-------------------------------------------------- |
|
5456 |
|
5457 // |
|
5458 eap_status_e eap_type_gsmsim_c::query_eap_identity( |
|
5459 const bool must_be_synchronous, |
|
5460 eap_variable_data_c * const identity, |
|
5461 const eap_am_network_id_c * const receive_network_id, |
|
5462 const u8_t eap_identifier) |
|
5463 { |
|
5464 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5465 |
|
5466 eap_variable_data_c IMSI(m_am_tools); |
|
5467 eap_variable_data_c pseudonym(m_am_tools); |
|
5468 eap_variable_data_c reauthentication_identity(m_am_tools); |
|
5469 |
|
5470 if (IMSI.get_is_valid() == false |
|
5471 || pseudonym.get_is_valid() == false |
|
5472 || reauthentication_identity.get_is_valid() == false) |
|
5473 { |
|
5474 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5475 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
5476 } |
|
5477 |
|
5478 // Here we swap the addresses. |
|
5479 eap_am_network_id_c send_network_id(m_am_tools, |
|
5480 receive_network_id->get_destination_id(), |
|
5481 receive_network_id->get_source_id(), |
|
5482 receive_network_id->get_type()); |
|
5483 |
|
5484 if (send_network_id.get_is_valid() == false) |
|
5485 { |
|
5486 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5487 return EAP_STATUS_RETURN(m_am_tools, eap_status_allocation_error); |
|
5488 } |
|
5489 |
|
5490 eap_status_e status = eap_status_process_general_error; |
|
5491 |
|
5492 if (m_state == eap_type_gsmsim_state_none) |
|
5493 { |
|
5494 status = new_handler( |
|
5495 receive_network_id, |
|
5496 true); |
|
5497 if (status != eap_status_ok) |
|
5498 { |
|
5499 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5500 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5501 } |
|
5502 } |
|
5503 |
|
5504 EAP_TRACE_DEBUG( |
|
5505 m_am_tools, |
|
5506 TRACE_FLAGS_DEFAULT, |
|
5507 (EAPL("eap_type_gsmsim_c::query_eap_identity(): eap_type_gsmsim_state_variable_e %d=%s.\n"), |
|
5508 m_state, |
|
5509 get_state_string())); |
|
5510 |
|
5511 |
|
5512 #if defined(USE_EAP_GSMSIM_VERIFY_STATES) |
|
5513 const eap_type_gsmsim_state_variable_e gsmsim_query_eap_identity_states[] = |
|
5514 { |
|
5515 eap_type_gsmsim_state_waiting_for_start_request, |
|
5516 eap_type_gsmsim_state_pseydonym_waiting_for_start_request, |
|
5517 eap_type_gsmsim_state_imsi_waiting_for_start_request, |
|
5518 eap_type_gsmsim_state_waiting_for_reauth_request, |
|
5519 }; |
|
5520 #endif //#if defined(USE_EAP_GSMSIM_VERIFY_STATES) |
|
5521 |
|
5522 |
|
5523 if (m_state == eap_type_gsmsim_state_waiting_for_identity_request |
|
5524 || (m_gsmsim_test_version == true |
|
5525 && m_state == eap_type_gsmsim_state_success)) // This one is for testing purposes. |
|
5526 { |
|
5527 m_last_eap_identifier = eap_identifier; |
|
5528 |
|
5529 eap_variable_data_c automatic_realm(m_am_tools); |
|
5530 |
|
5531 status = query_SIM_IMSI_or_pseudonym_or_reauthentication_id( |
|
5532 &IMSI, |
|
5533 &pseudonym, |
|
5534 &reauthentication_identity, |
|
5535 &automatic_realm, |
|
5536 &m_length_of_mnc, |
|
5537 must_be_synchronous, |
|
5538 gsmsim_payload_AT_ANY_ID_REQ, |
|
5539 eap_type_gsmsim_complete_query_eap_identity, |
|
5540 eap_identifier); |
|
5541 if (status == eap_status_pending_request) |
|
5542 { |
|
5543 // This is pending query, that will be completed by complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() call. |
|
5544 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5545 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5546 } |
|
5547 else if (status == eap_status_completed_request) |
|
5548 { |
|
5549 // This is already completed by complete_SIM_IMSI_or_pseudonym_or_reauthentication_id_query() call. |
|
5550 EAP_TRACE_DEBUG( |
|
5551 m_am_tools, |
|
5552 TRACE_FLAGS_DEFAULT, |
|
5553 (EAPL("eap_type_gsmsim_c::query_eap_identity(): ") |
|
5554 EAPL("completed returns eap_type_gsmsim_state_variable_e %d=%s.\n"), |
|
5555 m_state, |
|
5556 get_state_string())); |
|
5557 |
|
5558 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5559 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5560 } |
|
5561 else if (status != eap_status_ok) |
|
5562 { |
|
5563 // This is the error case. |
|
5564 restore_saved_previous_state(); |
|
5565 |
|
5566 EAP_TRACE_ERROR( |
|
5567 m_am_tools, |
|
5568 TRACE_FLAGS_DEFAULT, |
|
5569 (EAPL("eap_type_gsmsim_c::query_eap_identity(): ") |
|
5570 EAPL("error returns eap_type_gsmsim_state_variable_e %d=%s.\n"), |
|
5571 m_state, |
|
5572 get_state_string())); |
|
5573 |
|
5574 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5575 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5576 } |
|
5577 else // status == eap_status_ok |
|
5578 { |
|
5579 status = handle_eap_identity_query( |
|
5580 &send_network_id, |
|
5581 identity, |
|
5582 eap_identifier, |
|
5583 &IMSI, |
|
5584 &pseudonym, |
|
5585 &reauthentication_identity, |
|
5586 &automatic_realm, |
|
5587 m_length_of_mnc, |
|
5588 must_be_synchronous); |
|
5589 |
|
5590 if (status != eap_status_ok |
|
5591 && status != eap_status_completed_request) |
|
5592 { |
|
5593 restore_saved_previous_state(); |
|
5594 } |
|
5595 |
|
5596 EAP_TRACE_DEBUG( |
|
5597 m_am_tools, |
|
5598 TRACE_FLAGS_DEFAULT, |
|
5599 (EAPL("eap_type_gsmsim_c::query_eap_identity(): handle_eap_identity_query() ") |
|
5600 EAPL("returns eap_type_gsmsim_state_variable_e %d=%s.\n"), |
|
5601 m_state, |
|
5602 get_state_string())); |
|
5603 |
|
5604 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5605 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5606 } |
|
5607 } |
|
5608 #if defined(USE_EAP_GSMSIM_VERIFY_STATES) |
|
5609 else if (verify_states(gsmsim_query_eap_identity_states, |
|
5610 GSMSIM_STATE_COUNT(gsmsim_query_eap_identity_states)) == true) |
|
5611 #else |
|
5612 else if (m_state == eap_type_gsmsim_state_waiting_for_start_request |
|
5613 || m_state == eap_type_gsmsim_state_pseydonym_waiting_for_start_request |
|
5614 || m_state == eap_type_gsmsim_state_imsi_waiting_for_start_request |
|
5615 || m_state == eap_type_gsmsim_state_waiting_for_reauth_request) |
|
5616 #endif //#if defined(USE_EAP_GSMSIM_VERIFY_STATES) |
|
5617 { |
|
5618 // This is re-transmission request. We do not change our state. |
|
5619 // Just send EAP-Identity again. |
|
5620 if (m_NAI.get_is_valid_data() == true) |
|
5621 { |
|
5622 status = identity->set_copy_of_buffer(&m_NAI); |
|
5623 |
|
5624 EAP_TRACE_DEBUG( |
|
5625 m_am_tools, |
|
5626 TRACE_FLAGS_DEFAULT, |
|
5627 (EAPL("eap_type_gsmsim_c::query_eap_identity(): handle_eap_identity_query() ") |
|
5628 EAPL("returns eap_type_gsmsim_state_variable_e %d=%s.\n"), |
|
5629 m_state, |
|
5630 get_state_string())); |
|
5631 } |
|
5632 else |
|
5633 { |
|
5634 EAP_TRACE_ERROR( |
|
5635 m_am_tools, |
|
5636 TRACE_FLAGS_GSMSIM_ERROR, |
|
5637 (EAPL("ERROR: eap_type_gsmsim_c::query_eap_identity(): ") |
|
5638 EAPL("EAP-Request/Identity cannot be completed, identity (NAI) ") |
|
5639 EAPL("is missing. in eap_type_gsmsim_state_variable_e %d=%s.\n"), |
|
5640 m_state, |
|
5641 get_state_string())); |
|
5642 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5643 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
5644 } |
|
5645 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5646 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5647 } |
|
5648 else if (m_state == eap_type_gsmsim_state_pending_identity_query) |
|
5649 { |
|
5650 EAP_TRACE_DEBUG( |
|
5651 m_am_tools, |
|
5652 TRACE_FLAGS_DEFAULT, |
|
5653 (EAPL("eap_type_gsmsim_c::query_eap_identity(): ignores re-transmitted query_eap_identity()") |
|
5654 EAPL("in eap_type_gsmsim_state_variable_e %d=%s.\n"), |
|
5655 m_state, |
|
5656 get_state_string())); |
|
5657 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5658 return EAP_STATUS_RETURN(m_am_tools, eap_status_pending_request); |
|
5659 } |
|
5660 |
|
5661 |
|
5662 // Wrong message in this state. |
|
5663 EAP_TRACE_ERROR( |
|
5664 m_am_tools, |
|
5665 TRACE_FLAGS_GSMSIM_ERROR, |
|
5666 (EAPL("WARNING: eap_type_gsmsim_c::query_eap_identity(): ") |
|
5667 EAPL("Wrong message EAP-Request/Identity in eap_type_gsmsim_state_variable_e %d=%s.\n"), |
|
5668 m_state, |
|
5669 get_state_string())); |
|
5670 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5671 return EAP_STATUS_RETURN(m_am_tools, eap_status_header_corrupted); |
|
5672 } |
|
5673 |
|
5674 //-------------------------------------------------- |
|
5675 |
|
5676 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::eap_acknowledge( |
|
5677 const eap_am_network_id_c * const receive_network_id) |
|
5678 { |
|
5679 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5680 |
|
5681 eap_status_e status(eap_status_ok); |
|
5682 |
|
5683 if (m_state == eap_type_gsmsim_state_waiting_for_success |
|
5684 && m_wait_eap_success_packet == true) |
|
5685 { |
|
5686 status = finish_successful_authentication( |
|
5687 receive_network_id); |
|
5688 } |
|
5689 else |
|
5690 { |
|
5691 EAP_TRACE_DEBUG( |
|
5692 m_am_tools, |
|
5693 TRACE_FLAGS_DEFAULT, |
|
5694 (EAPL("ignored eap_acknowledge(): state %d=%s, is client %d\n"), |
|
5695 m_state, |
|
5696 get_state_string(), |
|
5697 (m_is_client == true))); |
|
5698 } |
|
5699 |
|
5700 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5701 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5702 } |
|
5703 |
|
5704 //-------------------------------------------------- |
|
5705 |
|
5706 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::set_initial_eap_identifier( |
|
5707 const eap_am_network_id_c * const receive_network_id, |
|
5708 const u8_t initial_identifier) |
|
5709 { |
|
5710 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5711 |
|
5712 eap_status_e status = new_handler( |
|
5713 receive_network_id, |
|
5714 false); |
|
5715 if (status != eap_status_ok) |
|
5716 { |
|
5717 EAP_TRACE_DEBUG( |
|
5718 m_am_tools, |
|
5719 TRACE_FLAGS_GSMSIM_ERROR, |
|
5720 (EAPL("ERROR: eap_type_gsmsim_c::set_initial_eap_identifier(): ") |
|
5721 EAPL("new_handler() failed, status %d.\n"), |
|
5722 status)); |
|
5723 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5724 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5725 } |
|
5726 |
|
5727 m_last_eap_identifier = static_cast<u8_t>(initial_identifier-1u); |
|
5728 |
|
5729 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5730 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5731 } |
|
5732 |
|
5733 //-------------------------------------------------- |
|
5734 |
|
5735 #if defined(_DEBUG) && defined(USE_EAP_GSMSIM_TEST_VECTORS) |
|
5736 #include "read_rand_and_triplets.h" |
|
5737 #endif //#if defined(_DEBUG) && defined(USE_EAP_GSMSIM_TEST_VECTORS) |
|
5738 |
|
5739 |
|
5740 // |
|
5741 EAP_FUNC_EXPORT eap_status_e eap_type_gsmsim_c::generate_nonce( |
|
5742 const u32_t nonce_size, |
|
5743 eap_variable_data_c * const nonce) |
|
5744 { |
|
5745 EAP_TRACE_BEGIN(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5746 |
|
5747 eap_status_e status = nonce->init(nonce_size); |
|
5748 if (status != eap_status_ok) |
|
5749 { |
|
5750 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5751 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5752 } |
|
5753 nonce->set_is_valid(); |
|
5754 nonce->set_data_length(nonce_size); |
|
5755 |
|
5756 #if defined(_DEBUG) && defined(USE_EAP_GSMSIM_TEST_VECTORS) |
|
5757 if (m_nonce_mt_file.get_is_valid_data() == true) |
|
5758 { |
|
5759 status = read_rand_from_file(m_am_tools, &m_nonce_mt_file, nonce); |
|
5760 if (status != eap_status_ok) |
|
5761 { |
|
5762 status = m_am_tools->get_crypto()->get_rand_bytes( |
|
5763 nonce->get_data(), |
|
5764 nonce->get_data_length()); |
|
5765 } |
|
5766 } |
|
5767 else |
|
5768 #endif //#if defined(_DEBUG) && defined(USE_EAP_GSMSIM_TEST_VECTORS) |
|
5769 { |
|
5770 status = m_am_tools->get_crypto()->get_rand_bytes( |
|
5771 nonce->get_data(), |
|
5772 nonce->get_data_length()); |
|
5773 } |
|
5774 |
|
5775 EAP_TRACE_END(m_am_tools, TRACE_FLAGS_DEFAULT); |
|
5776 return EAP_STATUS_RETURN(m_am_tools, status); |
|
5777 } |
|
5778 |
|
5779 //-------------------------------------------------- |
|
5780 |
|
5781 |
|
5782 |
|
5783 // End. |