From cae1734c597371e7c3ccd384434e638071843249 Mon Sep 17 00:00:00 2001 From: Nikias Bassen Date: Fri, 30 Sep 2016 20:43:37 +0200 Subject: restore: Add support for FirmwareUpdaterData request used for Secure Element firmware --- src/restore.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) diff --git a/src/restore.c b/src/restore.c index c9f2641..807047c 100644 --- a/src/restore.c +++ b/src/restore.c @@ -1739,6 +1739,166 @@ int restore_send_fud_data(restored_client_t restore, struct idevicerestore_clien return 0; } +plist_t restore_get_se_firmware_data(restored_client_t restore, struct idevicerestore_client_t* client, plist_t build_identity, plist_t p_info) +{ + const char *comp_name = "SE,Firmware"; + char *comp_path = NULL; + unsigned char* component_data = NULL; + unsigned int component_size = 0; + plist_t fwdict = NULL; + plist_t parameters = NULL; + plist_t request = NULL; + plist_t response = NULL; + int ret; + + if (build_identity_get_component_path(build_identity, comp_name, &comp_path) < 0) { + error("ERROR: Unable get path for '%s' component\n", comp_name); + return NULL; + } + + ret = extract_component(client->ipsw, comp_path, &component_data, &component_size); + free(comp_path); + comp_path = NULL; + if (ret < 0) { + error("ERROR: Unable to extract '%s' component\n", comp_name); + return NULL; + } + + /* create SE request */ + request = tss_request_new(NULL); + if (request == NULL) { + error("ERROR: Unable to create SE TSS request\n"); + free(component_data); + return NULL; + } + + parameters = plist_new_dict(); + + /* add manifest for current build_identity to parameters */ + tss_parameters_add_from_manifest(parameters, build_identity); + + /* add SE,* tags from info dictionary to parameters */ + plist_dict_merge(¶meters, p_info); + + /* add required tags for SE TSS request */ + tss_request_add_se_tags(request, parameters, NULL); + + plist_free(parameters); + + info("Sending SE TSS request...\n"); + response = tss_request_send(request, client->tss_url); + plist_free(request); + if (response == NULL) { + error("ERROR: Unable to fetch SE ticket\n"); + free(component_data); + return NULL; + } + + if (plist_dict_get_item(response, "SE,Ticket")) { + info("Received SE ticket\n"); + } else { + error("ERROR: No 'SE,Ticket' in TSS response, this might not work\n"); + } + + plist_dict_set_item(response, "FirmwareData", plist_new_data((char*)component_data, (uint64_t) component_size)); + free(component_data); + component_data = NULL; + component_size = 0; + + return response; +} + +int restore_send_firmware_updater_data(restored_client_t restore, struct idevicerestore_client_t* client, plist_t build_identity, plist_t message) +{ + plist_t arguments; + plist_t p_type, p_updater_name, p_loop_count, p_info; + plist_t loop_count_dict = NULL; + char *s_type = NULL; + plist_t dict = NULL; + plist_t fwdict = NULL; + char *s_updater_name = NULL; + int restore_error; + + if (idevicerestore_debug) { + debug("DEBUG: Got FirmwareUpdaterData request:\n", __func__); + debug_plist(message); + } + + arguments = plist_dict_get_item(message, "Arguments"); + if (!arguments || plist_get_node_type(arguments) != PLIST_DICT) { + error("ERROR: %s: Arguments missing or has invalid type!\n", __func__); + goto error_out; + } + + p_type = plist_dict_get_item(arguments, "MessageArgType"); + if (!p_type || (plist_get_node_type(p_type) != PLIST_STRING)) { + error("ERROR: %s: MessageArgType missing or has invalid type!\n", __func__); + goto error_out; + } + + p_updater_name = plist_dict_get_item(arguments, "MessageArgUpdaterName"); + if (!p_updater_name || (plist_get_node_type(p_updater_name) != PLIST_STRING)) { + error("ERROR: %s: MessageArgUpdaterName missing or has invalid type!\n", __func__); + goto error_out; + } + + p_loop_count = plist_dict_get_item(arguments, "MessageArgUpdaterLoopCount"); + if (p_loop_count) { + loop_count_dict = plist_new_dict(); + plist_dict_set_item(loop_count_dict, "LoopCount", plist_copy(p_loop_count)); + } + + plist_get_string_val(p_type, &s_type); + if (!s_type || strcmp(s_type, "FirmwareResponseData")) { + error("ERROR: %s: MessageArgType has unexpected value '%s'\n", __func__, s_type); + goto error_out; + } + free(s_type); + s_type = NULL; + + p_info = plist_dict_get_item(arguments, "MessageArgInfo"); + if (!p_info || (plist_get_node_type(p_info) != PLIST_DICT)) { + error("ERROR: %s: MessageArgInfo missing or has invalid type!\n", __func__); + goto error_out; + } + + plist_get_string_val(p_updater_name, &s_updater_name); + + if (strcmp(s_updater_name, "SE")) { + error("ERROR: %s: Got unknown updater name '%s'.", __func__, s_updater_name); + goto error_out; + } + free(s_updater_name); + s_updater_name = NULL; + + fwdict = restore_get_se_firmware_data(restore, client, build_identity, p_info); + if (fwdict == NULL) { + error("ERROR: %s: Couldn't get SE firmware data\n", __func__); + goto error_out; + } + + dict = plist_new_dict(); + plist_dict_set_item(dict, "FirmwareResponseData", fwdict); + + info("Sending FirmwareResponse data now...\n"); + restore_error = restored_send(restore, dict); + plist_free(dict); + if (restore_error != RESTORE_E_SUCCESS) { + error("ERROR: Couldn't send FirmwareResponse data (%d)\n", restore_error); + goto error_out; + } + + info("Done sending FirmwareUpdater data\n"); + + return 0; + +error_out: + free(s_type); + free(s_updater_name); + plist_free(loop_count_dict); + return -1; +} + int restore_handle_data_request_msg(struct idevicerestore_client_t* client, idevice_t device, restored_client_t restore, plist_t message, plist_t build_identity, const char* filesystem) { char* type = NULL; @@ -1806,6 +1966,13 @@ int restore_handle_data_request_msg(struct idevicerestore_client_t* client, idev } } + else if (!strcmp(type, "FirmwareUpdaterData")) { + if(restore_send_firmware_updater_data(restore, client, build_identity, message) < 0) { + error("ERROR: Unable to send FirmwareUpdater data\n"); + return -1; + } + } + else { // Unknown DataType!! error("Unknown data request '%s' received\n", type); -- cgit v1.1-32-gdbae