summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2016-09-30 20:43:37 +0200
committerGravatar Nikias Bassen2016-09-30 20:43:37 +0200
commitcae1734c597371e7c3ccd384434e638071843249 (patch)
treed40ac1aaf232efbe484f3c4296d2f754f4dad2f1
parent20607e3c7d061edd2b0333602b2627933c602747 (diff)
downloadidevicerestore-cae1734c597371e7c3ccd384434e638071843249.tar.gz
idevicerestore-cae1734c597371e7c3ccd384434e638071843249.tar.bz2
restore: Add support for FirmwareUpdaterData request used for Secure Element firmware
-rw-r--r--src/restore.c167
1 files changed, 167 insertions, 0 deletions
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(&parameters, 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);