summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/idevicerestore.c183
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");