diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/idevicerestore.c | 183 |
1 files changed, 93 insertions, 90 deletions
diff --git a/src/idevicerestore.c b/src/idevicerestore.c index ff9e98a..423d79c 100644 --- a/src/idevicerestore.c +++ b/src/idevicerestore.c @@ -564,95 +564,6 @@ int idevicerestore_start(struct idevicerestore_client_t* client) build_identity_print_information(build_identity); idevicerestore_progress(client, RESTORE_STEP_PREPARE, 0.0); - /* retrieve shsh blobs if required */ - if (tss_enabled) { - debug("Getting device's ECID for TSS request\n"); - /* fetch the device's ECID for the TSS request */ - if (get_ecid(client, &client->ecid) < 0) { - error("ERROR: Unable to find device ECID\n"); - return -1; - } - info("Found ECID " FMT_qu "\n", (long long unsigned int)client->ecid); - - if (client->build_major > 8) { - unsigned char* nonce = NULL; - int nonce_size = 0; - if (get_ap_nonce(client, &nonce, &nonce_size) < 0) { - /* the first nonce request with older firmware releases can fail and it's OK */ - info("NOTE: Unable to get nonce from device\n"); - } - - if (!client->nonce || (nonce_size != client->nonce_size) || (memcmp(nonce, client->nonce, nonce_size) != 0)) { - if (client->nonce) { - free(client->nonce); - } - client->nonce = nonce; - client->nonce_size = nonce_size; - } else { - free(nonce); - } - } - - if (get_tss_response(client, build_identity, &client->tss) < 0) { - error("ERROR: Unable to get SHSH blobs for this device\n"); - return -1; - } - } - - if (client->flags & FLAG_SHSHONLY) { - if (!tss_enabled) { - info("This device does not require a TSS record\n"); - return 0; - } - if (!client->tss) { - error("ERROR: could not fetch TSS record\n"); - plist_free(buildmanifest); - return -1; - } else { - char *bin = NULL; - uint32_t blen = 0; - plist_to_bin(client->tss, &bin, &blen); - if (bin) { - char zfn[1024]; - if (client->cache_dir) { - strcpy(zfn, client->cache_dir); - strcat(zfn, "/shsh"); - } else { - strcpy(zfn, "shsh"); - } - mkdir_with_parents(zfn, 0755); - sprintf(zfn+strlen(zfn), "/" FMT_qu "-%s-%s.shsh", (long long int)client->ecid, client->device->product_type, client->version); - struct stat fst; - if (stat(zfn, &fst) != 0) { - gzFile zf = gzopen(zfn, "wb"); - gzwrite(zf, bin, blen); - gzclose(zf); - info("SHSH saved to '%s'\n", zfn); - } else { - info("SHSH '%s' already present.\n", zfn); - } - free(bin); - } else { - error("ERROR: could not get TSS record data\n"); - } - plist_free(client->tss); - plist_free(buildmanifest); - return 0; - } - } - - /* verify if we have tss records if required */ - if ((tss_enabled) && (client->tss == NULL)) { - error("ERROR: Unable to proceed without a TSS record.\n"); - plist_free(buildmanifest); - return -1; - } - - if ((tss_enabled) && client->tss) { - /* fix empty dicts */ - fixup_tss(client->tss); - } - idevicerestore_progress(client, RESTORE_STEP_PREPARE, 0.1); // Get filesystem name from build identity char* fsname = NULL; @@ -700,7 +611,7 @@ int idevicerestore_start(struct idevicerestore_client_t* client) } } - if (!filesystem) { + if (!filesystem && !(client->flags & FLAG_SHSHONLY)) { char extfn[1024]; strcpy(extfn, tmpf); strcat(extfn, ".extract"); @@ -749,6 +660,98 @@ int idevicerestore_start(struct idevicerestore_client_t* client) } } + idevicerestore_progress(client, RESTORE_STEP_PREPARE, 0.2); + + /* retrieve shsh blobs if required */ + if (tss_enabled) { + debug("Getting device's ECID for TSS request\n"); + /* fetch the device's ECID for the TSS request */ + if (get_ecid(client, &client->ecid) < 0) { + error("ERROR: Unable to find device ECID\n"); + return -1; + } + info("Found ECID " FMT_qu "\n", (long long unsigned int)client->ecid); + + if (client->build_major > 8) { + unsigned char* nonce = NULL; + int nonce_size = 0; + if (get_ap_nonce(client, &nonce, &nonce_size) < 0) { + /* the first nonce request with older firmware releases can fail and it's OK */ + info("NOTE: Unable to get nonce from device\n"); + } + + if (!client->nonce || (nonce_size != client->nonce_size) || (memcmp(nonce, client->nonce, nonce_size) != 0)) { + if (client->nonce) { + free(client->nonce); + } + client->nonce = nonce; + client->nonce_size = nonce_size; + } else { + free(nonce); + } + } + + if (get_tss_response(client, build_identity, &client->tss) < 0) { + error("ERROR: Unable to get SHSH blobs for this device\n"); + return -1; + } + } + + if (client->flags & FLAG_SHSHONLY) { + if (!tss_enabled) { + info("This device does not require a TSS record\n"); + return 0; + } + if (!client->tss) { + error("ERROR: could not fetch TSS record\n"); + plist_free(buildmanifest); + return -1; + } else { + char *bin = NULL; + uint32_t blen = 0; + plist_to_bin(client->tss, &bin, &blen); + if (bin) { + char zfn[1024]; + if (client->cache_dir) { + strcpy(zfn, client->cache_dir); + strcat(zfn, "/shsh"); + } else { + strcpy(zfn, "shsh"); + } + mkdir_with_parents(zfn, 0755); + sprintf(zfn+strlen(zfn), "/" FMT_qu "-%s-%s.shsh", (long long int)client->ecid, client->device->product_type, client->version); + struct stat fst; + if (stat(zfn, &fst) != 0) { + gzFile zf = gzopen(zfn, "wb"); + gzwrite(zf, bin, blen); + gzclose(zf); + info("SHSH saved to '%s'\n", zfn); + } else { + info("SHSH '%s' already present.\n", zfn); + } + free(bin); + } else { + error("ERROR: could not get TSS record data\n"); + } + plist_free(client->tss); + plist_free(buildmanifest); + return 0; + } + } + + /* verify if we have tss records if required */ + if ((tss_enabled) && (client->tss == NULL)) { + error("ERROR: Unable to proceed without a TSS record.\n"); + plist_free(buildmanifest); + return -1; + } + + if ((tss_enabled) && client->tss) { + /* fix empty dicts */ + fixup_tss(client->tss); + } + idevicerestore_progress(client, RESTORE_STEP_PREPARE, 0.25); + // if the device is in normal mode, place device into recovery mode if (client->mode->index == MODE_NORMAL) { info("Entering recovery mode...\n"); |