diff --git a/euicc/es9p.c b/euicc/es9p.c index e235a79..06782b0 100644 --- a/euicc/es9p.c +++ b/euicc/es9p.c @@ -293,16 +293,68 @@ int es9p_cancel_session_r(struct euicc_ctx *ctx, const char *server_address, con return es9p_trans_json(ctx, ctx->http.server_address, "/gsma/rsp2/es9plus/cancelSession", ikey, idata, NULL, NULL, NULL); } -int es11_authenticate_client_r(struct euicc_ctx *ctx, char **smdp_list, const char *server_address, const char *transction_id, const char *b64_authenticate_server_response) +int es11_authenticate_client_r(struct euicc_ctx *ctx, char ***smdp_list, const char *server_address, const char *transction_id, const char *b64_authenticate_server_response) { - cJSON *eventEntries = NULL; + int fret = 0; + cJSON *j_eventEntries = NULL; + int j_eventEntries_size = 0; const char *ikey[] = {"transactionId", "authenticateServerResponse", NULL}; const char *idata[] = {ctx->http._internal.transaction_id, b64_authenticate_server_response, NULL}; const char *okey[] = {"eventEntries", NULL}; const char oobj[] = {1}; - void **optr[] = {(void **)&eventEntries, NULL}; + void **optr[] = {(void **)&j_eventEntries, NULL}; - return es9p_trans_json(ctx, ctx->http.server_address, "/gsma/rsp2/es9plus/authenticateClient", ikey, idata, okey, oobj, optr); + if (es9p_trans_json(ctx, ctx->http.server_address, "/gsma/rsp2/es9plus/authenticateClient", ikey, idata, okey, oobj, optr)) + { + return -1; + } + + if (j_eventEntries == NULL || !cJSON_IsArray(j_eventEntries)) + { + return -1; + } + + j_eventEntries_size = cJSON_GetArraySize(j_eventEntries); + + *smdp_list = malloc(sizeof(char *) * (j_eventEntries_size + 1)); + if (*smdp_list == NULL) + { + fret = -1; + goto err; + } + memset(*smdp_list, 0, sizeof(char *) * (j_eventEntries_size + 1)); + + for (int i = 0; i < j_eventEntries_size; i++) + { + cJSON *j_event = cJSON_GetArrayItem(j_eventEntries, i); + cJSON *j_eventType = cJSON_GetObjectItem(j_event, "rspServerAddress"); + + if (j_eventType == NULL || !cJSON_IsString(j_eventType)) + { + fret = -1; + goto err; + } + + (*smdp_list)[i] = strdup(j_eventType->valuestring); + } + + fret = 0; + goto exit; + +err: + if (*smdp_list) + { + for (int i = 0; i < j_eventEntries_size; i++) + { + free((*smdp_list)[i]); + } + free(*smdp_list); + *smdp_list = NULL; + } + +exit: + cJSON_Delete(j_eventEntries); + return fret; } int es9p_initiate_authentication(struct euicc_ctx *ctx) @@ -414,9 +466,25 @@ int es9p_cancel_session(struct euicc_ctx *ctx) return -1; } -int es11_authenticate_client(struct euicc_ctx *ctx, char **smdp_list) +int es11_authenticate_client(struct euicc_ctx *ctx, char ***smdp_list) { - return -1; + int fret; + + if (ctx->http._internal.b64_authenticate_server_response == NULL) + { + return -1; + } + + fret = es11_authenticate_client_r(ctx, smdp_list, ctx->http.server_address, ctx->http._internal.transaction_id, ctx->http._internal.b64_authenticate_server_response); + if (fret < 0) + { + return fret; + } + + free(ctx->http._internal.b64_authenticate_server_response); + ctx->http._internal.b64_authenticate_server_response = NULL; + + return fret; } int es9p_handle_notification(struct euicc_ctx *ctx, const char *b64_PendingNotification) @@ -426,3 +494,15 @@ int es9p_handle_notification(struct euicc_ctx *ctx, const char *b64_PendingNotif return es9p_trans_json(ctx, ctx->http.server_address, "/gsma/rsp2/es9plus/handleNotification", ikey, idata, NULL, NULL, NULL); } + +void es11_smdp_list_free_all(char **smdp_list) +{ + if (smdp_list) + { + for (int i = 0; smdp_list[i] != NULL; i++) + { + free(smdp_list[i]); + } + free(smdp_list); + } +} diff --git a/euicc/es9p.h b/euicc/es9p.h index 1f9d128..2dfcf27 100644 --- a/euicc/es9p.h +++ b/euicc/es9p.h @@ -13,7 +13,8 @@ int es9p_get_bound_profile_package(struct euicc_ctx *ctx); int es9p_authenticate_client(struct euicc_ctx *ctx); int es9p_cancel_session(struct euicc_ctx *ctx); -int es11_authenticate_client_r(struct euicc_ctx *ctx, char **smdp_list, const char *server_address, const char *transction_id, const char *b64_authenticate_server_response); -int es11_authenticate_client(struct euicc_ctx *ctx, char **smdp_list); +int es11_authenticate_client_r(struct euicc_ctx *ctx, char ***smdp_list, const char *server_address, const char *transction_id, const char *b64_authenticate_server_response); +int es11_authenticate_client(struct euicc_ctx *ctx, char ***smdp_list); int es9p_handle_notification(struct euicc_ctx *ctx, const char *b64_PendingNotification); +void es11_smdp_list_free_all(char **smdp_list); diff --git a/src/applet/profile/discovery.c b/src/applet/profile/discovery.c index 56aa7e1..5660894 100644 --- a/src/applet/profile/discovery.c +++ b/src/applet/profile/discovery.c @@ -9,94 +9,108 @@ #include #include +static const char *opt_string = "s:i:h?"; + static int applet_main(int argc, char **argv) { - // int opt; - // static const char *opt_string = "s:i:h?"; - - // char *smds = NULL; - // char *imei = NULL; - - // char *b64_euicc_challenge = NULL; - // char *b64_euicc_info_1 = NULL; - - // struct es10b_authenticate_server_param es10b_AuthenticateServer_param; - // char *b64_authenticate_server_response = NULL; - - // struct es11_authenticate_client_resp es11_AuthenticateClient_resp; - - // opt = getopt(argc, argv, opt_string); - // while (opt != -1) - // { - // switch (opt) - // { - // case 's': - // smds = strdup(optarg); - // break; - // case 'i': - // imei = strdup(optarg); - // break; - // case 'h': - // case '?': - // printf("Usage: %s [OPTIONS]\r\n", argv[0]); - // printf("\t -s SM-DS Domain\r\n"); - // printf("\t -i IMEI\r\n"); - // printf("\t -h This help info\r\n"); - // return -1; - // break; - // } - // opt = getopt(argc, argv, opt_string); - // } - - // if (smds == NULL) - // { - // // smds = "prod.smds.rsp.goog"; - // // smds = "lpa.live.esimdiscovery.com"; - // smds = "lpa.ds.gsma.com"; - // } - - // euicc_ctx.http.server_address = smds; - - // jprint_progress("es10b_get_euicc_challenge"); - // if (es10b_get_euicc_challenge_r(&euicc_ctx, &b64_euicc_challenge)) - // { - // jprint_error("es10b_get_euicc_challenge", NULL); - // return -1; - // } - - // jprint_progress("es10b_get_euicc_info"); - // if (es10b_get_euicc_info_r(&euicc_ctx, &b64_euicc_info_1)) - // { - // jprint_error("es10b_get_euicc_info", NULL); - // return -1; - // } - - // jprint_progress("es9p_InitiateAuthentication"); - // if (es9p_initiate_authentication_r(&euicc_ctx, &es10b_AuthenticateServer_param, b64_euicc_challenge, b64_euicc_info_1)) - // { - // jprint_error("es11_initiate_authentication", euicc_ctx.http.status.message); - // return -1; - // } - - // es10b_AuthenticateServer_param.matchingId = NULL; - // es10b_AuthenticateServer_param.imei = imei; - - // jprint_progress("es10b_authenticate_server"); - // if (es10b_authenticate_server_r(&euicc_ctx, &b64_authenticate_server_response, &es10b_AuthenticateServer_param)) - // { - // jprint_error("es10b_authenticate_server", NULL); - // return -1; - // } - - // jprint_progress("es11_authenticate_client"); - // if (es11_authenticate_client_r(&euicc_ctx, &es11_AuthenticateClient_resp, b64_authenticate_server_response)) - // { - // jprint_error("es11_authenticate_client", es11_AuthenticateClient_resp.status); - // return -1; - // } - - // jprint_success((cJSON *)es11_AuthenticateClient_resp.cjson_array_result); - return -1; + int fret; + + int opt; + + char *smds = NULL; + char *imei = NULL; + + char **smdp_list = NULL; + + cJSON *jdata = NULL; + + opt = getopt(argc, argv, opt_string); + while (opt != -1) + { + switch (opt) + { + case 's': + smds = strdup(optarg); + break; + case 'i': + imei = strdup(optarg); + break; + case 'h': + case '?': + printf("Usage: %s [OPTIONS]\r\n", argv[0]); + printf("\t -s SM-DS Domain\r\n"); + printf("\t -i IMEI\r\n"); + printf("\t -h This help info\r\n"); + return -1; + break; + } + opt = getopt(argc, argv, opt_string); + } + + if (smds == NULL) + { + // smds = "prod.smds.rsp.goog"; + // smds = "lpa.live.esimdiscovery.com"; + smds = "lpa.ds.gsma.com"; + } + + euicc_ctx.http.server_address = smds; + + jprint_progress("es10b_get_euicc_challenge_and_info"); + if (es10b_get_euicc_challenge_and_info(&euicc_ctx)) + { + jprint_error("es10b_get_euicc_challenge_and_info", NULL); + goto err; + } + + jprint_progress("es9p_initiate_authentication"); + if (es9p_initiate_authentication(&euicc_ctx)) + { + jprint_error("es9p_initiate_authentication", euicc_ctx.http.status.message); + goto err; + } + + jprint_progress("es10b_authenticate_server"); + if (es10b_authenticate_server(&euicc_ctx, NULL, imei)) + { + jprint_error("es10b_authenticate_server", NULL); + goto err; + } + + jprint_progress("es11_authenticate_client"); + if (es11_authenticate_client(&euicc_ctx, &smdp_list)) + { + jprint_error("es11_authenticate_client", NULL); + goto err; + } + + jdata = cJSON_CreateArray(); + if (jdata == NULL) + { + goto err; + } + + for (int i = 0; smdp_list[i] != NULL; i++) + { + cJSON *jsmdp = cJSON_CreateString(smdp_list[i]); + if (jsmdp == NULL) + { + goto err; + } + cJSON_AddItemToArray(jdata, jsmdp); + } + + jprint_success(jdata); + + fret = 0; + goto exit; + +err: + fret = -1; +exit: + es11_smdp_list_free_all(smdp_list); + euicc_http_cleanup(&euicc_ctx); + return fret; } struct applet_entry applet_profile_discovery = {