summaryrefslogtreecommitdiffstats
path: root/src/idevicerestore.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/idevicerestore.c')
-rw-r--r--src/idevicerestore.c228
1 files changed, 1 insertions, 227 deletions
diff --git a/src/idevicerestore.c b/src/idevicerestore.c
index 0726285..56bc44a 100644
--- a/src/idevicerestore.c
+++ b/src/idevicerestore.c
@@ -26,7 +26,6 @@
#include <getopt.h>
#include <plist/plist.h>
#include <zlib.h>
-#include <openssl/sha.h>
#include "dfu.h"
#include "tss.h"
@@ -139,165 +138,6 @@ static int load_version_data(struct idevicerestore_client_t* client)
return 0;
}
-int get_latest_fw(struct idevicerestore_client_t* client, char** fwurl, unsigned char* sha1buf)
-{
- *fwurl = NULL;
- memset(sha1buf, '\0', 20);
-
- plist_t n1 = plist_access_path(client->version_data, 2, "MobileDeviceMajorVersionsByProductType", client->device->product);
- if (!n1 || (plist_dict_get_size(n1) == 0)) {
- error("%s: ERROR: Can't find MobileDeviceMajorVersionsByProductType/%s dict in version data\n", __func__, client->device->product);
- return -1;
- }
-
- char* strval = NULL;
- plist_t n2 = plist_dict_get_item(n1, "SameAs");
- if (n2) {
- plist_get_string_val(n2, &strval);
- }
- if (strval) {
- n1 = plist_access_path(client->version_data, 2, "MobileDeviceMajorVersionsByProductType", strval);
- free(strval);
- strval = NULL;
- if (!n1 || (plist_dict_get_size(n1) == 0)) {
- error("%s: ERROR: Can't find MobileDeviceMajorVersionsByProductType/%s dict in version data\n", __func__, client->device->product);
- return -1;
- }
- }
-
- plist_dict_iter iter = NULL;
- plist_dict_new_iter(n1, &iter);
- if (!iter) {
- error("%s: ERROR: Can't get dict iter\n", __func__);
- return -1;
- }
- n2 = NULL;
- char* key = NULL;
- plist_t val = NULL;
- do {
- plist_dict_next_item(n1, iter, &key, &val);
- if (key) {
- n2 = val;
- free(key);
- }
- } while (val);
- free(iter);
-
- if (!n2) {
- error("%s: ERROR: Can't get last node?!\n", __func__);
- return -1;
- }
-
- uint64_t major = 0;
- if (plist_get_node_type(n2) == PLIST_ARRAY) {
- uint32_t sz = plist_array_get_size(n2);
- plist_t n3 = plist_array_get_item(n2, sz-1);
- plist_get_uint_val(n3, &major);
- } else {
- plist_get_uint_val(n2, &major);
- }
-
- if (major == 0) {
- error("%s: ERROR: Can't find major version?!\n", __func__);
- return -1;
- }
-
- char majstr[32]; // should be enough for a uint64_t value
- sprintf(majstr, FMT_qu, (long long unsigned int)major);
- n1 = plist_access_path(client->version_data, 7, "MobileDeviceSoftwareVersionsByVersion", majstr, "MobileDeviceSoftwareVersions", client->device->product, "Unknown", "Universal", "Restore");
- if (!n1) {
- error("%s: ERROR: Can't get Unknown/Universal/Restore node?!\n", __func__);
- return -1;
- }
-
- n2 = plist_dict_get_item(n1, "BuildVersion");
- if (!n2 || (plist_get_node_type(n2) != PLIST_STRING)) {
- error("%s: ERROR: Can't get build version node?!\n", __func__);
- return -1;
- }
-
- strval = NULL;
- plist_get_string_val(n2, &strval);
-
- n1 = plist_access_path(client->version_data, 5, "MobileDeviceSoftwareVersionsByVersion", majstr, "MobileDeviceSoftwareVersions", client->device->product, strval);
- if (!n1) {
- error("%s: ERROR: Can't get MobileDeviceSoftwareVersions/%s node?!\n", __func__, strval);
- free(strval);
- return -1;
- }
- free(strval);
-
- strval = NULL;
- n2 = plist_dict_get_item(n1, "SameAs");
- if (n2) {
- plist_get_string_val(n2, &strval);
- }
- if (strval) {
- n1 = plist_access_path(client->version_data, 5, "MobileDeviceSoftwareVersionsByVersion", majstr, "MobileDeviceSoftwareVersions", client->device->product, strval);
- free(strval);
- strval = NULL;
- if (!n1 || (plist_dict_get_size(n1) == 0)) {
- error("%s: ERROR: Can't get MobileDeviceSoftwareVersions/%s dict\n", __func__, client->device->product);
- return -1;
- }
- }
-
- n2 = plist_access_path(n1, 2, "Update", "BuildVersion");
- if (n2) {
- strval = NULL;
- plist_get_string_val(n2, &strval);
- if (strval) {
- n1 = plist_access_path(client->version_data, 5, "MobileDeviceSoftwareVersionsByVersion", majstr, "MobileDeviceSoftwareVersions", client->device->product, strval);
- free(strval);
- strval = NULL;
- }
- }
-
- n2 = plist_access_path(n1, 2, "Restore", "FirmwareURL");
- if (!n2 || (plist_get_node_type(n2) != PLIST_STRING)) {
- error("%s: ERROR: Can't get FirmwareURL node\n", __func__);
- return -1;
- }
-
- plist_get_string_val(n2, fwurl);
-
- n2 = plist_access_path(n1, 2, "Restore", "FirmwareSHA1");
- if (n2 && plist_get_node_type(n2) == PLIST_STRING) {
- strval = NULL;
- plist_get_string_val(n2, &strval);
- if (strval) {
- if (strlen(strval) == 40) {
- int i;
- int v;
- for (i = 0; i < 40; i+=2) {
- v = 0;
- sscanf(strval+i, "%02x", &v);
- sha1buf[i/2] = (unsigned char)v;
- }
- }
- free(strval);
- }
- }
-
- return 0;
-}
-
-static int sha1_verify_fp(FILE* f, unsigned char* expected_sha1)
-{
- unsigned char tsha1[20];
- char buf[8192];
- if (!f) return 0;
- SHA_CTX sha1ctx;
- SHA1_Init(&sha1ctx);
- rewind(f);
- while (!feof(f)) {
- size_t sz = fread(buf, 1, 8192, f);
- SHA1_Update(&sha1ctx, (const void*)buf, sz);
- }
- SHA1_Final(tsha1, &sha1ctx);
- return (memcmp(expected_sha1, tsha1, 20) == 0) ? 1 : 0;
-}
-
int main(int argc, char* argv[]) {
int opt = 0;
int optindex = 0;
@@ -510,77 +350,11 @@ int main(int argc, char* argv[]) {
}
if (latest) {
- char* fwurl = NULL;
- unsigned char isha1[20];
- if ((get_latest_fw(client, &fwurl, isha1) < 0) || !fwurl) {
- error("ERROR: can't get URL for latest firmware\n");
- return -1;
- }
- char* fwfn = strrchr(fwurl, '/');
- if (!fwfn) {
- error("ERROR: can't get local filename for firmware ipsw\n");
- return -1;
- }
- fwfn++;
-
- info("Latest firmware is %s\n", fwfn);
-
- char fwlfn[256];
- sprintf(fwlfn, "cache/%s", fwfn);
-
- int need_dl = 0;
- unsigned char zsha1[20] = {0, };
- FILE* f = fopen(fwlfn, "rb");
- if (f) {
- if (memcmp(zsha1, isha1, 20) != 0) {
- info("Verifying '%s'...\n", fwlfn);
- if (sha1_verify_fp(f, isha1)) {
- info("Checksum matches.\n");
- } else {
- info("Checksum does not match.\n");
- need_dl = 1;
- }
- }
- fclose(f);
- } else {
- need_dl = 1;
- }
-
- int res = 0;
- if (need_dl) {
- if (strncmp(fwurl, "protected:", 10) == 0) {
- error("ERROR: Can't download '%s' because it needs a purchase.\n", fwfn);
- res = -1;
- } else {
- remove(fwlfn);
- info("Downloading latest firmware (%s)\n", fwurl);
- download_to_file(fwurl, fwlfn);
- if (memcmp(isha1, zsha1, 20) != 0) {
- info("\nVerifying '%s'...\n", fwlfn);
- FILE* f = fopen(fwlfn, "rb");
- if (f) {
- if (sha1_verify_fp(f, isha1)) {
- info("Checksum matches.\n");
- } else {
- error("ERROR: File download failed (checksum mismatch).\n");
- res = -1;
- }
- fclose(f);
- } else {
- error("ERROR: Can't open '%s' for checksum verification\n", fwlfn);
- res = -1;
- }
- }
- }
- }
-
+ int res = ipsw_download_latest_fw(client->version_data, client->device->product, "cache", &ipsw);
if (res != 0) {
- free(fwurl);
return res;
} else {
- ipsw = strdup(fwlfn);
client->ipsw = ipsw;
- free(fwurl);
}
}