2 * Network Configuration Module
4 * Copyright (c) 2000 - 2012 Samsung Electronics Co., Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
24 #include "wifi-tel-intf.h"
25 #include "network-state.h"
28 #define SIM_RAND_DATA_LEN 16
29 #define SIM_AUTH_MAX_RESP_DATA_LEN 128
30 #define SIM_AUTH_SRES_LEN 4
31 #define SIM_AUTH_KC_LEN 8
33 #define AKA_RAND_DATA_LEN 16
34 #define AKA_AUTN_DATA_LEN 16
35 #define AKA_AUTH_RES_MAX_LEN 16
36 #define AKA_AUTH_RES_MIN_LEN 4
37 #define AKA_AUTH_CK_LEN 16
38 #define AKA_AUTH_IK_LEN 16
40 struct wifii_authentication_data {
43 int authentication_key_length;
47 char *authentication_key;
52 static struct wifii_authentication_data *wifi_authdata;
54 static void *__netconfig_wifi_free_wifi_authdata(
55 struct wifii_authentication_data *data)
59 g_free(data->resp_data);
60 if (data->authentication_key)
61 g_free(data->authentication_key);
62 if (data->cipher_data)
63 g_free(data->cipher_data);
64 if (data->integrity_data)
65 g_free(data->integrity_data);
74 static void __netconfig_wifi_clean_authentication(void)
76 netconfig_tel_deinit();
78 wifi_authdata = __netconfig_wifi_free_wifi_authdata(wifi_authdata);
81 static gboolean __netconfig_wifi_get_sim_imsi(Wifi *wifi,
82 GDBusMethodInvocation *context)
86 TelSimImsiInfo_t imsi_info;
89 handle = (TapiHandle *)netconfig_tel_init();
91 ERR("tapi_init failed");
92 netconfig_error_fail_get_imsi(context);
96 ERR("before tel_get_sim_imsi");
97 ret = tel_get_sim_imsi(handle, &imsi_info);
98 ERR("after tel_get_sim_imsi");
99 if (ret != TAPI_API_SUCCESS) {
100 ERR("Failed tel_get_sim_imsi() : [%d]", ret);
101 netconfig_error_fail_get_imsi(context);
105 imsi = g_strdup_printf("%s%s%s", imsi_info.szMcc,
106 imsi_info.szMnc, imsi_info.szMsin);
108 wifi_complete_get_sim_imsi(wifi, context, imsi);
114 void __netconfig_response_sim_authentication(TapiHandle *handle,
115 int result, void *data, void *user_data)
117 if (wifi_authdata != NULL)
118 wifi_authdata = __netconfig_wifi_free_wifi_authdata(wifi_authdata);
120 wifi_authdata = g_try_new0(struct wifii_authentication_data, 1);
122 TelSimAuthenticationResponse_t *auth_resp =
123 (TelSimAuthenticationResponse_t *) data;
124 if (auth_resp == NULL) {
125 ERR("the auth response is NULL");
127 wifi_authdata->auth_result = -1;
130 wifi_authdata->auth_result = auth_resp->auth_result;
132 if (auth_resp->auth_result == TAPI_SIM_AUTH_NO_ERROR) {
133 wifi_authdata->resp_length = auth_resp->resp_length;
134 wifi_authdata->authentication_key_length =
135 auth_resp->authentication_key_length;
137 if (wifi_authdata->resp_data != NULL)
138 g_free(wifi_authdata->resp_data);
140 wifi_authdata->resp_data = g_strdup(auth_resp->resp_data);
142 if (wifi_authdata->authentication_key != NULL)
143 g_free(wifi_authdata->authentication_key);
145 wifi_authdata->authentication_key =
146 g_strdup(auth_resp->authentication_key);
148 ERR("the result error for sim auth : [%d]", auth_resp->auth_result);
150 wifi_authdata->resp_length = 0;
151 wifi_authdata->authentication_key_length = 0;
155 void __netconfig_response_aka_authentication(TapiHandle *handle,
156 int result, void *data, void *user_data)
158 if (wifi_authdata != NULL)
159 wifi_authdata = __netconfig_wifi_free_wifi_authdata(wifi_authdata);
161 wifi_authdata = g_try_new0(struct wifii_authentication_data, 1);
163 TelSimAuthenticationResponse_t *auth_resp =
164 (TelSimAuthenticationResponse_t *) data;
165 if (auth_resp == NULL) {
166 ERR("the auth response is NULL");
168 wifi_authdata->auth_result = -1;
171 wifi_authdata->auth_result = auth_resp->auth_result;
173 if (auth_resp->auth_result == TAPI_SIM_AUTH_NO_ERROR) {
174 wifi_authdata->resp_length = auth_resp->resp_length;
175 wifi_authdata->cipher_length = auth_resp->cipher_length;
176 wifi_authdata->integrity_length = auth_resp->integrity_length;
178 if (wifi_authdata->resp_data != NULL)
179 g_free(wifi_authdata->resp_data);
181 wifi_authdata->resp_data = g_strdup(auth_resp->resp_data);
183 if (wifi_authdata->cipher_data != NULL)
184 g_free(wifi_authdata->cipher_data);
186 wifi_authdata->cipher_data = g_strdup(auth_resp->cipher_data);
188 if (wifi_authdata->integrity_data != NULL)
189 g_free(wifi_authdata->integrity_data);
191 wifi_authdata->integrity_data = g_strdup(auth_resp->integrity_data);
193 ERR("the result error for aka auth : [%d]", auth_resp->auth_result);
195 if (auth_resp->auth_result == TAPI_SIM_AUTH_SQN_FAILURE ||
196 auth_resp->auth_result == TAPI_SIM_AUTH_SYNCH_FAILURE) {
197 wifi_authdata->resp_length = auth_resp->resp_length;
199 if (wifi_authdata->resp_data != NULL)
200 g_free(wifi_authdata->resp_data);
202 wifi_authdata->resp_data = g_strdup(auth_resp->resp_data);
207 static gboolean __netconfig_wifi_req_sim_auth(GArray *rand_data,
208 GDBusMethodInvocation *context)
213 TelSimAuthenticationData_t auth_data;
215 if (rand_data == NULL)
218 if (rand_data->len != SIM_RAND_DATA_LEN) {
219 ERR("wrong rand data len : [%d]", rand_data->len);
221 netconfig_error_fail_req_sim_auth_wrong_param(context);
225 if ((ret = g_array_get_element_size(rand_data)) != 1) {
226 ERR("wrong rand data size : [%d]", ret);
228 netconfig_error_fail_req_sim_auth_wrong_param(context);
232 memset(&auth_data, 0, sizeof(auth_data));
234 auth_data.auth_type = TAPI_SIM_AUTH_TYPE_GSM;
235 auth_data.rand_length = SIM_RAND_DATA_LEN;
237 for (i=0; i<rand_data->len; i++)
238 auth_data.rand_data[i] = g_array_index(rand_data, guint8, i);
240 handle = (TapiHandle *)netconfig_tel_init();
241 if (handle == NULL) {
242 netconfig_error_fail_req_sim_auth(context);
246 ret = tel_req_sim_authentication(handle,
247 &auth_data, __netconfig_response_sim_authentication, NULL);
248 if (ret != TAPI_API_SUCCESS) {
249 ERR("Failed tel_req_sim_authentication() : [%d]", ret);
251 netconfig_error_fail_req_sim_auth(context);
258 static netconfig_error_e __netconfig_wifi_req_aka_auth(
259 GArray *rand_data, GArray *autn_data, GDBusMethodInvocation *context)
264 TelSimAuthenticationData_t auth_data;
266 if (rand_data == NULL || autn_data == NULL)
267 return NETCONFIG_ERROR_FAILED_REQ_SIM_AUTH;
269 if (rand_data->len != AKA_RAND_DATA_LEN) {
270 ERR("wrong rand data len : [%d]", rand_data->len);
272 return NETCONFIG_ERROR_FAILED_REQ_SIM_AUTH_WRONG_PARAM;
275 if (autn_data->len != AKA_AUTN_DATA_LEN) {
276 ERR("wrong autn data len : [%d]", autn_data->len);
278 return NETCONFIG_ERROR_FAILED_REQ_SIM_AUTH_WRONG_PARAM;
281 if ((ret = g_array_get_element_size(rand_data)) != 1) {
282 ERR("wrong rand data size : [%d]", ret);
284 return NETCONFIG_ERROR_FAILED_REQ_SIM_AUTH_WRONG_PARAM;
287 if ((ret = g_array_get_element_size(autn_data)) != 1) {
288 ERR("wrong autn data size : [%d]", ret);
290 return NETCONFIG_ERROR_FAILED_REQ_SIM_AUTH_WRONG_PARAM;
293 memset(&auth_data, 0, sizeof(auth_data));
295 auth_data.auth_type = TAPI_SIM_AUTH_TYPE_3G;
296 auth_data.rand_length = AKA_RAND_DATA_LEN;
297 auth_data.autn_length = AKA_AUTN_DATA_LEN;
299 for (i=0; i<rand_data->len; i++)
300 auth_data.rand_data[i] = g_array_index(rand_data, guint8, i);
302 for (i=0; i<autn_data->len; i++)
303 auth_data.autn_data[i] = g_array_index(autn_data, guint8, i);
305 handle = (TapiHandle *)netconfig_tel_init();
306 if (handle == NULL) {
307 return NETCONFIG_ERROR_FAILED_REQ_SIM_AUTH;
310 ret = tel_req_sim_authentication(handle, &auth_data,
311 __netconfig_response_aka_authentication, NULL);
313 if (ret != TAPI_API_SUCCESS) {
314 ERR("Failed tel_req_sim_authentication() : [%d]", ret);
316 return NETCONFIG_ERROR_FAILED_REQ_SIM_AUTH;
318 return NETCONFIG_NO_ERROR;
321 static gboolean __netconfig_wifi_get_sim_authdata(Wifi *wifi,
322 GDBusMethodInvocation *context)
324 GArray *array = NULL;
326 if (wifi_authdata == NULL) {
327 DBG("the status error : no response yet");
328 netconfig_error_fail_get_sim_auth_delay(context);
332 if (wifi_authdata->auth_result == TAPI_SIM_AUTH_NO_ERROR) {
333 if (wifi_authdata->resp_length == SIM_AUTH_SRES_LEN &&
334 wifi_authdata->authentication_key_length == SIM_AUTH_KC_LEN) {
335 array = g_array_sized_new(FALSE, FALSE, sizeof(guchar),
336 SIM_AUTH_SRES_LEN+SIM_AUTH_KC_LEN);
337 g_array_append_vals(array, wifi_authdata->resp_data,
339 g_array_append_vals(array, wifi_authdata->authentication_key,
342 ERR("auth data length is wrong, SRES = [%d], Kc = [%d]",
343 wifi_authdata->resp_length,
344 wifi_authdata->authentication_key_length);
345 netconfig_error_fail_get_sim_auth_wrong_data(context);
346 __netconfig_wifi_clean_authentication();
350 ERR("failed auth result = [%d]", wifi_authdata->auth_result);
351 netconfig_error_fail_get_sim_auth_wrong_data(context);
352 __netconfig_wifi_clean_authentication();
356 wifi_complete_get_sim_auth(wifi, context, array->data);
357 g_array_free (array, TRUE);
358 __netconfig_wifi_clean_authentication();
362 static gboolean __netconfig_wifi_get_aka_authdata(Wifi *wifi, GDBusMethodInvocation *context)
364 GArray *array = NULL;
367 if (wifi_authdata == NULL) {
368 DBG("the status error : no response yet");
369 netconfig_error_fail_get_sim_auth_delay(context);
373 switch (wifi_authdata->auth_result) {
374 case TAPI_SIM_AUTH_NO_ERROR:
377 case TAPI_SIM_AUTH_SQN_FAILURE:
378 case TAPI_SIM_AUTH_SYNCH_FAILURE:
379 array = g_array_sized_new(FALSE, FALSE, sizeof(guchar),
380 wifi_authdata->resp_length+1);
381 res_len = (guchar)((wifi_authdata->resp_length-1) & 0xff);
383 g_array_append_vals(array, &res_len, 1);
384 g_array_append_vals(array, wifi_authdata->resp_data,
385 wifi_authdata->resp_length);
387 wifi_complete_get_aka_auth(wifi, context, array->data);
388 g_array_free (array, TRUE);
390 __netconfig_wifi_clean_authentication();
395 netconfig_error_fail_get_sim_auth_wrong_data(context);
396 __netconfig_wifi_clean_authentication();
400 if ((wifi_authdata->resp_length >= AKA_AUTH_RES_MIN_LEN ||
401 wifi_authdata->resp_length <= AKA_AUTH_RES_MAX_LEN) &&
402 wifi_authdata->cipher_length == AKA_AUTH_CK_LEN &&
403 wifi_authdata->integrity_length == AKA_AUTH_IK_LEN) {
404 array = g_array_sized_new(FALSE, FALSE, sizeof(guchar),
405 wifi_authdata->resp_length+AKA_AUTH_CK_LEN+AKA_AUTH_IK_LEN+1);
407 res_len = (guchar)((wifi_authdata->resp_length-1) & 0xff);
408 g_array_append_vals(array, &res_len, 1);
409 g_array_append_vals(array, wifi_authdata->resp_data,
410 wifi_authdata->resp_length);
411 g_array_append_vals(array, wifi_authdata->cipher_data,
413 g_array_append_vals(array, wifi_authdata->integrity_data,
416 ERR("auth data length is wrong, res = [%d], Kc = [%d], Ki = [%d]",
417 wifi_authdata->resp_length, wifi_authdata->cipher_length,
418 wifi_authdata->integrity_length);
420 netconfig_error_fail_get_sim_auth_wrong_data(context);
421 __netconfig_wifi_clean_authentication();
425 wifi_complete_get_aka_auth(wifi, context, array->data);
426 g_array_free (array, TRUE);
427 __netconfig_wifi_clean_authentication();
432 gboolean handle_get_sim_imsi(Wifi *wifi, GDBusMethodInvocation *context)
438 g_return_val_if_fail(wifi != NULL, FALSE);
440 ret = __netconfig_wifi_get_sim_imsi(wifi, context);
445 gboolean handle_req_sim_auth(Wifi *wifi, GDBusMethodInvocation *context, GVariant *rand_data)
447 gboolean result = TRUE;
448 GArray *rand_data_garray;
451 guchar *out_auth_data;
455 DBG("Request SIM Authentication");
457 g_return_val_if_fail(wifi != NULL, FALSE);
459 g_variant_get(rand_data, "ay", &iter);
460 length = g_variant_iter_n_children(iter);
461 out_auth_data = g_new0(guchar, length);
463 while (g_variant_iter_loop(iter, "y", &byte)) {
464 *(out_auth_data + i) = byte;
467 g_variant_iter_free(iter);
469 rand_data_garray = g_array_sized_new(FALSE, FALSE, sizeof(guchar), length);
470 memcpy(rand_data_garray->data, out_auth_data, length);
471 g_free(out_auth_data);
472 rand_data_garray->len = length;
474 result = __netconfig_wifi_req_sim_auth(rand_data_garray, context);
475 g_array_free(rand_data_garray, FALSE);
478 wifi_complete_req_sim_auth(wifi, context, result);
484 gboolean handle_req_aka_auth(Wifi *wifi, GDBusMethodInvocation *context, GVariant *rand_data, GVariant *autn_data)
486 netconfig_error_e ret = NETCONFIG_NO_ERROR;
487 gboolean result = FALSE;
490 guchar *out_auth_data;
493 GArray *rand_data_garray;
494 GArray *autn_data_garray;
496 DBG("Request AKA Authentication");
498 g_return_val_if_fail(wifi != NULL, FALSE);
500 g_variant_get(rand_data, "ay", &iter);
501 length = g_variant_iter_n_children(iter);
502 out_auth_data = g_new0(guchar, length);
503 while (g_variant_iter_loop(iter, "y", &byte)) {
504 *(out_auth_data + i) = byte;
507 g_variant_iter_free(iter);
509 rand_data_garray = g_array_sized_new(FALSE, FALSE, sizeof(guchar), length);
510 memcpy(rand_data_garray->data, out_auth_data, length);
511 g_free(out_auth_data);
512 rand_data_garray->len = length;
515 g_variant_get(autn_data, "ay", &iter);
516 length = g_variant_iter_n_children(iter);
517 out_auth_data = g_new0(guchar, length);
518 while (g_variant_iter_loop(iter, "y", &byte)) {
519 *(out_auth_data + i) = byte;
522 g_variant_iter_free(iter);
524 autn_data_garray = g_array_sized_new(FALSE, FALSE, sizeof(guchar), length);
525 memcpy(autn_data_garray->data, out_auth_data, length);
526 g_free(out_auth_data);
527 autn_data_garray->len = length;
529 ret = __netconfig_wifi_req_aka_auth(rand_data_garray, autn_data_garray, context);
530 if (ret == NETCONFIG_NO_ERROR) {
532 wifi_complete_req_aka_auth(wifi, context, result);
533 } else if (ret == NETCONFIG_ERROR_FAILED_REQ_SIM_AUTH_WRONG_PARAM) {
534 netconfig_error_dbus_method_return(context,
535 NETCONFIG_ERROR_FAILED_REQ_SIM_AUTH_WRONG_PARAM, "FailReqSimAuthWrongParam");
537 netconfig_error_dbus_method_return(context,
538 NETCONFIG_ERROR_FAILED_REQ_SIM_AUTH, "FailReqSimAuth");
541 g_array_free(rand_data_garray, FALSE);
542 g_array_free(autn_data_garray, FALSE);
547 gboolean handle_get_sim_auth(Wifi *wifi, GDBusMethodInvocation *context)
551 DBG("Get SIM Authdata");
553 g_return_val_if_fail(wifi != NULL, FALSE);
555 ret = __netconfig_wifi_get_sim_authdata(wifi, context);
559 gboolean handle_get_aka_auth(Wifi *wifi, GDBusMethodInvocation *context)
563 DBG("Get AKA Authdata");
565 g_return_val_if_fail(wifi != NULL, FALSE);
567 ret = __netconfig_wifi_get_aka_authdata(wifi, context);