diff --git a/.gitignore b/.gitignore index 52798e6e..c7cc324b 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ autom4te.cache compile config.* configure +configure~ depcomp install-sh libtool @@ -25,4 +26,5 @@ missing */tsschecker* stamp-h1 xcuserdata -configure~ +.build_complete +.idea diff --git a/tsschecker/all.h b/tsschecker/all.h index 1ca0af85..422345d4 100644 --- a/tsschecker/all.h +++ b/tsschecker/all.h @@ -10,9 +10,10 @@ #define all_h #ifdef DEBUG // this is for developing with Xcode -#define TSSCHECKER_VERSION_COUNT "Debug" -#define TSSCHECKER_VERSION_SHA "Build: " __DATE__ " " __TIME__ +#define TSSCHECKER_BUILD_TYPE "DEBUG" +#define TSSCHECKER_VERSION_SHA "Build: " __DATE__ " " __TIME__ "" #else +#define TSSCHECKER_BUILD_TYPE "RELEASE" #endif #endif /* all_h */ diff --git a/tsschecker/main.c b/tsschecker/main.c index 78c24eb8..a28fc8bd 100644 --- a/tsschecker/main.c +++ b/tsschecker/main.c @@ -58,6 +58,7 @@ static struct option longopts[] = { { "sepnonce", required_argument, NULL, 9 }, { "raw", required_argument, NULL, 10 }, { "bbsnum", required_argument, NULL, 11 }, + { "server-url", required_argument, NULL, 12 }, { "generator", required_argument, NULL, 'g' }, { NULL, 0, NULL, 0 } }; @@ -84,6 +85,7 @@ void cmd_help(){ printf(" --sepnonce NONCE\t\tmanually specify SEP Nonce instead of using random ones (not required for saving blobs)\n"); printf(" --bbsnum SNUM\t\tmanually specify BbSNUM in HEX to save valid BBTickets (not required for saving blobs)\n\n"); printf(" --save-path PATH\t\tspecify output path for saving shsh blobs\n"); + printf(" --server-url URL\t\tmanually specify TSS server URL\n"); printf(" --beta\t\t\trequest tickets for a beta instead of normal release (use with -o)\n"); printf(" --list-devices\t\tlist all known devices\n"); printf(" --list-ios\t\tlist all known firmware versions\n"); @@ -149,7 +151,7 @@ char *parseNonce(const char *nonce, size_t *parsedLen){ int main(int argc, const char * argv[]) { int err = 0; int isSigned = 0; - printf("tsschecker version: 0."TSSCHECKER_VERSION_COUNT".0-"TSSCHECKER_VERSION_SHA"\n"); + printf("tsschecker version: 0."TSSCHECKER_VERSION_COUNT".0-"TSSCHECKER_VERSION_SHA"-"TSSCHECKER_BUILD_TYPE"\n"); printf("%s\n",fragmentzip_version()); dbglog = 1; @@ -171,6 +173,7 @@ int main(int argc, const char * argv[]) { jssytok_t *firmwareTokens = NULL; const char *rawFilePath = NULL; + const char *serverUrl = NULL; if (argc == 1){ cmd_help(); @@ -278,6 +281,9 @@ int main(int argc, const char * argv[]) { case 11: // only long option: "bbsnum" bbsnum = optarg; break; + case 12: // only long option: "server-url" + serverUrl = optarg; + break; default: cmd_help(); return -1; @@ -298,7 +304,7 @@ int main(int argc, const char * argv[]) { fclose(f); printf("Sending TSS request:\n%s",buf); - char *rsp = tss_request_send_raw(buf, NULL, (int*)&bufSize); + char *rsp = tss_request_send_raw(buf, serverUrl, (int*)&bufSize); printf("TSS server returned:\n%s\n",rsp); free(rsp); @@ -425,13 +431,13 @@ int main(int argc, const char * argv[]) { }else{ //request ticket if (buildmanifest) { - isSigned = isManifestSignedForDevice(buildmanifest, &devVals, &versVals); + isSigned = isManifestSignedForDevice(buildmanifest, &devVals, &versVals, serverUrl); }else{ if (!devVals.deviceModel) reterror(-3,"[TSSC] please specify a device for this option\n\tuse -h for more help\n"); if (!versVals.version && !versVals.buildID) reterror(-5,"[TSSC] please specify an firmware version or buildID for this option\n\tuse -h for more help\n"); - isSigned = isVersionSignedForDevice(firmwareTokens, &versVals, &devVals); + isSigned = isVersionSignedForDevice(firmwareTokens, &versVals, &devVals, serverUrl); } if (isSigned >=0) printf("\n%s %s for device %s %s being signed!\n",(versVals.buildID) ? "Build" : "iOS" ,(versVals.buildID ? versVals.buildID : versVals.version),devVals.deviceModel, (isSigned) ? "IS" : "IS NOT"); diff --git a/tsschecker/tss.c b/tsschecker/tss.c index 9fa14a96..8a2ec3cc 100644 --- a/tsschecker/tss.c +++ b/tsschecker/tss.c @@ -48,11 +48,14 @@ #include "tss.h" #include "endianness.h" +#define AUTH_VERSION "850.0.2" + #ifdef WIN32 -#define TSS_CLIENT_VERSION_STRING "libauthinstall_Win-850.0.2" +#define TSS_CLIENT_VERSION_STRING "libauthinstall_Win-"AUTH_VERSION"" #else -#define TSS_CLIENT_VERSION_STRING "libauthinstall-850.0.2" +#define TSS_CLIENT_VERSION_STRING "libauthinstall-"AUTH_VERSION"" #endif + #define ECID_STRSIZE 0x20 #define GET_RAND(min, max) ((rand() % (max - min)) + min) @@ -460,6 +463,34 @@ int tss_parameters_add_from_manifest(plist_t parameters, plist_t build_identity) } node = NULL; + /* add Baobab,BoardID */ + node = plist_dict_get_item(build_identity, "Baobab,BoardID"); + if (node) { + plist_dict_set_item(parameters, "Baobab,BoardID", plist_copy(node)); + } + node = NULL; + + /* add Baobab,ChipID */ + node = plist_dict_get_item(build_identity, "Baobab,ChipID"); + if (node) { + plist_dict_set_item(parameters, "Baobab,ChipID", plist_copy(node)); + } + node = NULL; + + /* add Baobab,ManifestEpoch */ + node = plist_dict_get_item(build_identity, "Baobab,ManifestEpoch"); + if (node) { + plist_dict_set_item(parameters, "Baobab,ManifestEpoch", plist_copy(node)); + } + node = NULL; + + /* add Baobab,SecurityDomain */ + node = plist_dict_get_item(build_identity, "Baobab,SecurityDomain"); + if (node) { + plist_dict_set_item(parameters, "Baobab,SecurityDomain", plist_copy(node)); + } + node = NULL; + /* add eUICC,ChipID */ node = plist_dict_get_item(build_identity, "eUICC,ChipID"); if (node) { @@ -752,12 +783,19 @@ int tss_request_add_ap_tags(plist_t request, plist_t parameters, plist_t overrid return -1; } - /* do not populate BasebandFirmware, only in baseband request */ - if ((strcmp(key, "BasebandFirmware") == 0)) { - free(key); - continue; - } + /* do not populate BasebandFirmware, only in baseband request */ + if ((strcmp(key, "BasebandFirmware") == 0)) { + free(key); + continue; + } + + /* do not populate Savage, only in Savage request */ + if ((strncmp(key, "Savage",sizeof("Savage")-1) == 0)) { + free(key); + continue; + } + /* only used with diagnostics firmware */ if ((strcmp(key, "Diags") == 0)) { free(key); @@ -1188,7 +1226,7 @@ int tss_request_add_yonkers_tags(plist_t request, plist_t parameters, plist_t ov plist_t manifest_node = plist_dict_get_item(parameters, "Manifest"); if (!manifest_node || plist_get_node_type(manifest_node) != PLIST_DICT) { - error("ERROR: %s: Unable to get restore manifest from parameters\n", __func__); + tsserror("ERROR: %s: Unable to get restore manifest from parameters\n", __func__); return -1; } @@ -1199,7 +1237,7 @@ int tss_request_add_yonkers_tags(plist_t request, plist_t parameters, plist_t ov /* add SEP */ node = plist_access_path(manifest_node, 2, "SEP", "Digest"); if (!node) { - error("ERROR: Unable to get SEP digest from manifest\n"); + tsserror("ERROR: Unable to get SEP digest from manifest\n"); return -1; } plist_t dict = plist_new_dict(); @@ -1212,7 +1250,7 @@ int tss_request_add_yonkers_tags(plist_t request, plist_t parameters, plist_t ov for (i = 0; i < (int)(sizeof(keys) / sizeof(keys[0])); ++i) { node = plist_dict_get_item(parameters, keys[i]); if (!node) { - error("ERROR: %s: Unable to find required %sin parameters\n", __func__, keys[i]); + tsserror("ERROR: %s: Unable to find required %sin parameters\n", __func__, keys[i]); } plist_dict_set_item(request, keys[i], plist_copy(node)); node = NULL; @@ -1267,7 +1305,7 @@ int tss_request_add_yonkers_tags(plist_t request, plist_t parameters, plist_t ov free(iter); if (comp_name == NULL) { - error("ERROR: No Yonkers node for %s/%lu\n", (isprod) ? "Production" : "Development", (unsigned long)fabrevision); + tsserror("ERROR: No Yonkers node for %s/%lu\n", (isprod) ? "Production" : "Development", (unsigned long)fabrevision); return -1; } @@ -1298,7 +1336,7 @@ int tss_request_add_vinyl_tags(plist_t request, plist_t parameters, plist_t over plist_t manifest_node = plist_dict_get_item(parameters, "Manifest"); if (!manifest_node || plist_get_node_type(manifest_node) != PLIST_DICT) { - error("ERROR: %s: Unable to get restore manifest from parameters\n", __func__); + tsserror("ERROR: %s: Unable to get restore manifest from parameters\n", __func__); return -1; } @@ -1351,7 +1389,7 @@ int tss_request_add_rose_tags(plist_t request, plist_t parameters, plist_t overr plist_t manifest_node = plist_dict_get_item(parameters, "Manifest"); if (!manifest_node || plist_get_node_type(manifest_node) != PLIST_DICT) { - error("ERROR: %s: Unable to get restore manifest from parameters\n", __func__); + tsserror("ERROR: %s: Unable to get restore manifest from parameters\n", __func__); return -1; } @@ -1440,11 +1478,11 @@ int tss_request_add_veridian_tags(plist_t request, plist_t parameters, plist_t o plist_t manifest_node = plist_dict_get_item(parameters, "Manifest"); if (!manifest_node || plist_get_node_type(manifest_node) != PLIST_DICT) { - error("ERROR: %s: Unable to get restore manifest from parameters\n", __func__); + tsserror("ERROR: %s: Unable to get restore manifest from parameters\n", __func__); return -1; } - /* add tags indicating we want to get the Rap,Ticket */ + /* add tags indicating we want to get the BMU,Ticket */ plist_dict_set_item(request, "@BBTicket", plist_new_bool(1)); plist_dict_set_item(request, "@BMU,Ticket", plist_new_bool(1)); @@ -1517,6 +1555,83 @@ int tss_request_add_veridian_tags(plist_t request, plist_t parameters, plist_t o return 0; } +int tss_request_add_tcon_tags(plist_t request, plist_t parameters, plist_t overrides) +{ + plist_t node = NULL; + + plist_t manifest_node = plist_dict_get_item(parameters, "Manifest"); + if (!manifest_node || plist_get_node_type(manifest_node) != PLIST_DICT) { + tsserror("ERROR: %s: Unable to get restore manifest from parameters\n", __func__); + return -1; + } + + /* add tags indicating we want to get the Baobab,Ticket */ + plist_dict_set_item(request, "@BBTicket", plist_new_bool(1)); + plist_dict_set_item(request, "@Baobab,Ticket", plist_new_bool(1)); + + uint64_t u64val = 0; + uint8_t bval = 0; + uint8_t isprod = 0; + + u64val = _plist_dict_get_uint(parameters, "Baobab,BoardID"); + plist_dict_set_item(request, "Baobab,BoardID", plist_new_uint(u64val)); + + u64val = _plist_dict_get_uint(parameters, "Baobab,ChipID"); + plist_dict_set_item(request, "Baobab,ChipID", plist_new_uint(u64val)); + + node = plist_dict_get_item(parameters, "Baobab,ECID"); + if (node) { + plist_dict_set_item(request, "Baobab,ECID", plist_copy(node)); + } + + u64val = _plist_dict_get_uint(parameters, "Baobab,Life"); + plist_dict_set_item(request, "Baobab,Life", plist_new_uint(u64val)); + + u64val = _plist_dict_get_uint(parameters, "Baobab,ManifestEpoch"); + plist_dict_set_item(request, "Baobab,ManifestEpoch", plist_new_uint(u64val)); + + isprod = _plist_dict_get_bool(parameters, "Baobab,ProductionMode"); + plist_dict_set_item(request, "Baobab,ProductionMode", plist_new_bool(isprod)); + + u64val = _plist_dict_get_uint(parameters, "Baobab,SecurityDomain"); + plist_dict_set_item(request, "Baobab,SecurityDomain", plist_new_uint(u64val)); + + node = plist_dict_get_item(parameters, "Baobab,UpdateNonce"); + if (node) { + plist_dict_set_item(request, "Baobab,UpdateNonce", plist_copy(node)); + } + + char *comp_name = NULL; + plist_dict_iter iter = NULL; + plist_dict_new_iter(manifest_node, &iter); + while (iter) { + node = NULL; + comp_name = NULL; + plist_dict_next_item(manifest_node, iter, &comp_name, &node); + if (comp_name == NULL) { + node = NULL; + break; + } + if (strncmp(comp_name, "Baobab,", 7) == 0) { + plist_t manifest_entry = plist_copy(node); + + plist_dict_remove_item(manifest_entry, "Info"); + plist_dict_set_item(manifest_entry, "EPRO", plist_new_bool(isprod)); + + /* finally add entry to request */ + plist_dict_set_item(request, comp_name, manifest_entry); + } + free(comp_name); + } + free(iter); + + /* apply overrides */ + if (overrides) { + plist_dict_merge(&request, overrides); + } + return 0; +} + static size_t tss_write_callback(char* data, size_t size, size_t nmemb, tss_response* response) { size_t total = size * nmemb; if (total != 0) { @@ -1637,16 +1752,16 @@ char* tss_request_send_raw(char* request, const char* server_url_string, int* re // ignoring error that occurs when saving blobs on certain A8(X) devices and earlier break; } else { - error("ERROR: tss_send_request: Unhandled status code %d\n", status_code); + tsserror("ERROR: tss_send_request: Unhandled status code %d\n", status_code); } } if (status_code != 0) { if (response && strstr(response->content, "MESSAGE=") != NULL) { char* message = strstr(response->content, "MESSAGE=") + strlen("MESSAGE="); - error("ERROR: TSS request failed (status=%d, message=%s)\n", status_code, message); + tsserror("ERROR: TSS request failed (status=%d, message=%s)\n", status_code, message); } else { - error("ERROR: TSS request failed: %s (status=%d)\n", curl_error_message, status_code); + tsserror("ERROR: TSS request failed: %s (status=%d)\n", curl_error_message, status_code); } free(request); if (response) @@ -1679,7 +1794,7 @@ plist_t tss_request_send(plist_t tss_request, const char* server_url_string) { if (rsp){ char* tss_data = strstr(rsp, " 0); + isSigned = ((apticket = tss_request_send(tssreq, server_url_string)) > 0); if (print_tss_response) debug_plist(apticket); if (isSigned && save_shshblobs){ @@ -998,7 +1002,7 @@ int isManifestBufSignedForDevice(char *buildManifestBuffer, t_devicevals *devVal if (tssrequest(&tssreq2, buildManifestBuffer, devVals, basebandMode)){ warning("[TSSR] failed to build tssrequest for alternative installType\n"); }else{ - apticket2 = tss_request_send(tssreq2, NULL); + apticket2 = tss_request_send(tssreq2, server_url_string); if (print_tss_response) debug_plist(apticket2); } if (tssreq2) plist_free(tssreq2); @@ -1013,7 +1017,7 @@ int isManifestBufSignedForDevice(char *buildManifestBuffer, t_devicevals *devVal devVals->apnonce = (char *)0x1337; devVals->installType = kInstallTypeErase; if (!tssrequest(&tssreq2, buildManifestBuffer, devVals, kBasebandModeWithoutBaseband)){ - apticket3 = tss_request_send(tssreq2, NULL); + apticket3 = tss_request_send(tssreq2, server_url_string); if (print_tss_response) debug_plist(apticket3); } devVals->parsedApnonceLen = apnonceLen; @@ -1098,7 +1102,7 @@ int isManifestBufSignedForDevice(char *buildManifestBuffer, t_devicevals *devVal #undef reterror } -int isManifestSignedForDevice(const char *buildManifestPath, t_devicevals *devVals, t_iosVersion *versVals){ +int isManifestSignedForDevice(const char *buildManifestPath, t_devicevals *devVals, t_iosVersion *versVals, const char* server_url_string){ int isSigned = 0; #define reterror(a ...) {error(a); isSigned = -1; goto error;} plist_t manifest = NULL; @@ -1144,7 +1148,7 @@ int isManifestSignedForDevice(const char *buildManifestPath, t_devicevals *devVa reterror("[TSSC] selected device can't be used with that buildmanifest\n"); checkedDeviceModel: - isSigned = isManifestBufSignedForDevice(bufManifest, devVals, versVals->basebandMode); + isSigned = isManifestBufSignedForDevice(bufManifest, devVals, versVals->basebandMode, server_url_string); error: if (manifest) plist_free(manifest); @@ -1153,7 +1157,7 @@ int isManifestSignedForDevice(const char *buildManifestPath, t_devicevals *devVa #undef reterror } -int isVersionSignedForDevice(jssytok_t *firmwareTokens, t_iosVersion *versVals, t_devicevals *devVals){ +int isVersionSignedForDevice(jssytok_t *firmwareTokens, t_iosVersion *versVals, t_devicevals *devVals, const char* server_url_string){ #define reterror(a ... ) {error(a); goto error;} int nocacheorig = nocache; if (versVals->version && atoi(versVals->version) <= 3) { @@ -1183,7 +1187,7 @@ int isVersionSignedForDevice(jssytok_t *firmwareTokens, t_iosVersion *versVals, if (cursigned) { info("[TSSC] skipping duplicated build\n"); - }else if ((isSignedOne = isManifestBufSignedForDevice(buildManifest, devVals, versVals->basebandMode)) >= 0){ + }else if ((isSignedOne = isManifestBufSignedForDevice(buildManifest, devVals, versVals->basebandMode, server_url_string)) >= 0){ cursigned |= (isSigned > 0); isSigned = (isSignedOne > 0 || isSigned > 0); diff --git a/tsschecker/tsschecker.h b/tsschecker/tsschecker.h index a785070c..220e433f 100644 --- a/tsschecker/tsschecker.h +++ b/tsschecker/tsschecker.h @@ -97,9 +97,9 @@ char *getBuildManifest(char *url, const char *device, const char *version, const t_bbdevice getBBDeviceInfo(const char *deviceModel); int tssrequest(plist_t *tssrequest, char *buildManifest, t_devicevals *devVals, t_basebandMode basebandMode); -int isManifestSignedForDevice(const char *buildManifestPath, t_devicevals *devVals, t_iosVersion *versVals); -int isManifestBufSignedForDevice(char *buildManifestBuffer, t_devicevals *devVals, t_basebandMode basebandMode); -int isVersionSignedForDevice(jssytok_t *firmwareTokens, t_iosVersion *versVals, t_devicevals *devVals); +int isManifestSignedForDevice(const char *buildManifestPath, t_devicevals *devVals, t_iosVersion *versVals, const char* server_url_string); +int isManifestBufSignedForDevice(char *buildManifestBuffer, t_devicevals *devVals, t_basebandMode basebandMode, const char* server_url_string); +int isVersionSignedForDevice(jssytok_t *firmwareTokens, t_iosVersion *versVals, t_devicevals *devVals, const char* server_url_string); jssytok_t *getFirmwaresForDevice(const char *device, jssytok_t *tokens, int isOta);