diff options
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | src/common.h | 2 | ||||
-rw-r--r-- | src/idevicerestore.c | 346 | ||||
-rw-r--r-- | src/idevicerestore.h | 14 | ||||
-rw-r--r-- | src/tss.c | 345 | ||||
-rw-r--r-- | src/tss.h | 2 |
6 files changed, 708 insertions, 4 deletions
diff --git a/configure.ac b/configure.ac index 7df4c15..eb585c8 100644 --- a/configure.ac +++ b/configure.ac @@ -41,6 +41,7 @@ PKG_CHECK_MODULES(libplist, libplist-2.0 >= $LIBPLIST_VERSION) PKG_CHECK_MODULES(libzip, libzip >= $LIBZIP_VERSION) PKG_CHECK_MODULES(libcurl, libcurl >= $LIBCURL_VERSION) PKG_CHECK_MODULES(zlib, zlib) +PKG_CHECK_MODULES(uuid, uuid) # optional PKG_CHECK_MODULES(openssl, openssl >= $OPENSSL_VERSION, have_openssl=yes, have_openssl=no) @@ -51,7 +52,7 @@ AC_C_BIGENDIAN([AC_DEFINE([__BIG_ENDIAN__], [1], [big endian])], GLOBAL_CFLAGS="-Wno-multichar -O2" AC_LDADD="" -AC_LDFLAGS="" +AC_LDFLAGS="-luuid" AC_MSG_CHECKING([whether we need platform-specific build settings]) case ${host_os} in *mingw32*|*cygwin*) diff --git a/src/common.h b/src/common.h index 215d18a..5d23299 100644 --- a/src/common.h +++ b/src/common.h @@ -82,6 +82,8 @@ struct idevicerestore_entry_t { struct idevicerestore_client_t { int flags; plist_t tss; + plist_t tss_localpolicy; + plist_t tss_recoveryos_root_ticket; char* tss_url; plist_t version_data; uint64_t ecid; diff --git a/src/idevicerestore.c b/src/idevicerestore.c index 36b86b8..2ceec6d 100644 --- a/src/idevicerestore.c +++ b/src/idevicerestore.c @@ -1074,10 +1074,23 @@ int idevicerestore_start(struct idevicerestore_client_t* client) if (client->flags & FLAG_QUIT) { return -1; } + 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->build_major >= 20) { + if (get_local_policy_tss_response(client, build_identity, &client->tss_localpolicy) < 0) { + error("ERROR: Unable to get SHSH blobs for this device (local policy)\n"); + return -1; + } + if (get_recoveryos_root_ticket_tss_response(client, build_identity, &client->tss_recoveryos_root_ticket) < + 0) { + error("ERROR: Unable to get SHSH blobs for this device (recovery OS Root Ticket)\n"); + return -1; + } + } + if (stashbag_commit_required) { plist_t ticket = plist_dict_get_item(client->tss, "ApImg4Ticket"); if (!ticket || plist_get_node_type(ticket) != PLIST_DATA) { @@ -1991,6 +2004,79 @@ plist_t build_manifest_get_build_identity_for_model_with_restore_behavior(plist_ return NULL; } +plist_t build_manifest_get_build_identity_for_model_with_restore_behavior_and_global_signing( + plist_t build_manifest, + const char *hardware_model, + const char *behavior, + uint8_t global_signing) +{ + plist_t build_identities_array = plist_dict_get_item(build_manifest, "BuildIdentities"); + if (!build_identities_array || plist_get_node_type(build_identities_array) != PLIST_ARRAY) { + error("ERROR: Unable to find build identities node\n"); + return NULL; + } + + uint32_t i; + for (i = 0; i < plist_array_get_size(build_identities_array); i++) { + plist_t ident = plist_array_get_item(build_identities_array, i); + if (!ident || plist_get_node_type(ident) != PLIST_DICT) { + continue; + } + plist_t info_dict = plist_dict_get_item(ident, "Info"); + if (!info_dict || plist_get_node_type(ident) != PLIST_DICT) { + continue; + } + plist_t devclass = plist_dict_get_item(info_dict, "DeviceClass"); + if (!devclass || plist_get_node_type(devclass) != PLIST_STRING) { + continue; + } + char *str = NULL; + plist_get_string_val(devclass, &str); + if (strcasecmp(str, hardware_model) != 0) { + free(str); + continue; + } + free(str); + str = NULL; + + plist_t global_signing_node = plist_dict_get_item(info_dict, "VariantSupportsGlobalSigning"); + if (!global_signing_node) { + if (global_signing) { + continue; + } + } else { + uint8_t is_global_signing; + plist_get_bool_val(global_signing_node, &is_global_signing); + + if (global_signing && !is_global_signing) { + continue; + } else if (!global_signing && is_global_signing) { + continue; + } + } + + if (behavior) { + plist_t rbehavior = plist_dict_get_item(info_dict, "RestoreBehavior"); + if (!rbehavior || plist_get_node_type(rbehavior) != PLIST_STRING) { + continue; + } + plist_get_string_val(rbehavior, &str); + if (strcasecmp(str, behavior) != 0) { + free(str); + continue; + } else { + free(str); + return plist_copy(ident); + } + free(str); + } else { + return plist_copy(ident); + } + } + + return NULL; +} + plist_t build_manifest_get_build_identity_for_model(plist_t build_manifest, const char *hardware_model) { return build_manifest_get_build_identity_for_model_with_restore_behavior(build_manifest, hardware_model, NULL); @@ -2267,6 +2353,266 @@ int get_tss_response(struct idevicerestore_client_t* client, plist_t build_ident return 0; } +int get_recoveryos_root_ticket_tss_response(struct idevicerestore_client_t* client, plist_t build_identity, plist_t* tss) { + plist_t request = NULL; + plist_t response = NULL; + *tss = NULL; + + /* populate parameters */ + plist_t parameters = plist_new_dict(); + + /* ApECID */ + plist_dict_set_item(parameters, "ApECID", plist_new_uint(client->ecid)); + plist_dict_set_item(parameters, "Ap,LocalBoot", plist_new_bool(0)); + + /* ApNonce */ + if (client->nonce) { + plist_dict_set_item(parameters, "ApNonce", plist_new_data((const char*)client->nonce, client->nonce_size)); + } + unsigned char* sep_nonce = NULL; + int sep_nonce_size = 0; + get_sep_nonce(client, &sep_nonce, &sep_nonce_size); + + /* ApSepNonce */ + if (sep_nonce) { + plist_dict_set_item(parameters, "ApSepNonce", plist_new_data((const char*)sep_nonce, sep_nonce_size)); + free(sep_nonce); + } + + /* ApProductionMode */ + plist_dict_set_item(parameters, "ApProductionMode", plist_new_bool(1)); + + /* ApSecurityMode */ + if (client->image4supported) { + plist_dict_set_item(parameters, "ApSecurityMode", plist_new_bool(1)); + } + + tss_parameters_add_from_manifest(parameters, build_identity); + + /* create basic request */ + /* Adds @BBTicket, @HostPlatformInfo, @VersionInfo, @UUID */ + request = tss_request_new(NULL); + if (request == NULL) { + error("ERROR: Unable to create TSS request\n"); + plist_free(parameters); + return -1; + } + + /* add common tags from manifest */ + /* Adds Ap,OSLongVersion, AppNonce, @ApImg4Ticket */ + if (tss_request_add_ap_img4_tags(request, parameters) < 0) { + error("ERROR: Unable to add AP IMG4 tags to TSS request\n"); + plist_free(request); + plist_free(parameters); + return -1; + } + + /* add AP tags from manifest */ + if (tss_request_add_common_tags(request, parameters, NULL) < 0) { + error("ERROR: Unable to add common tags to TSS request\n"); + plist_free(request); + plist_free(parameters); + return -1; + } + + /* add AP tags from manifest */ + /* Fills digests & co */ + if (tss_request_add_ap_recovery_tags(request, parameters, NULL) < 0) { + error("ERROR: Unable to add common tags to TSS request\n"); + plist_free(request); + plist_free(parameters); + return -1; + } + + /* send request and grab response */ + response = tss_request_send(request, client->tss_url); + if (response == NULL) { + info("ERROR: Unable to send TSS request\n"); + plist_free(request); + plist_free(parameters); + return -1; + } + // request_add_ap_tags + + info("Received SHSH blobs\n"); + + plist_free(request); + plist_free(parameters); + + *tss = response; + + return 0; +} + +int get_recovery_os_local_policy_tss_response( + struct idevicerestore_client_t* client, + plist_t build_identity, + plist_t* tss, + plist_t args) { + plist_t request = NULL; + plist_t response = NULL; + *tss = NULL; + + /* populate parameters */ + plist_t parameters = plist_new_dict(); + plist_dict_set_item(parameters, "ApECID", plist_new_uint(client->ecid)); + plist_dict_set_item(parameters, "Ap,LocalBoot", plist_new_bool(1)); + + plist_dict_set_item(parameters, "ApProductionMode", plist_new_bool(1)); + if (client->image4supported) { + plist_dict_set_item(parameters, "ApSecurityMode", plist_new_bool(1)); + plist_dict_set_item(parameters, "ApSupportsImg4", plist_new_bool(1)); + } else { + plist_dict_set_item(parameters, "ApSupportsImg4", plist_new_bool(0)); + } + + tss_parameters_add_from_manifest(parameters, build_identity); + + // Add Ap,LocalPolicy + uint8_t digest[SHA384_DIGEST_LENGTH]; + SHA384(lpol_file, lpol_file_length, digest); + plist_t lpol = plist_new_dict(); + plist_dict_set_item(lpol, "Digest", plist_new_data(digest, SHA384_DIGEST_LENGTH)); + plist_dict_set_item(lpol, "Trusted", plist_new_bool(1)); + plist_dict_set_item(parameters, "Ap,LocalPolicy", lpol); + + plist_t im4m_hash = plist_dict_get_item(args, "Ap,NextStageIM4MHash"); + plist_dict_set_item(parameters, "Ap,NextStageIM4MHash", plist_copy(im4m_hash)); + + plist_t nonce_hash = plist_dict_get_item(args, "Ap,RecoveryOSPolicyNonceHash"); + plist_dict_set_item(parameters, "Ap,RecoveryOSPolicyNonceHash", plist_copy(nonce_hash)); + + plist_t vol_uuid_node = plist_dict_get_item(args, "Ap,VolumeUUID"); + char* vol_uuid_str = malloc(40); + plist_get_string_val(vol_uuid_node, &vol_uuid_str); + uuid_t vol_uuid; + int ret = uuid_parse(vol_uuid_str, vol_uuid); + if (ret != 0) { + error("failed to parse Ap,VolumeUUID (%s) with code %d\n", vol_uuid_str, ret); + return -1; + } + free(vol_uuid_str); + plist_dict_set_item(parameters, "Ap,VolumeUUID", plist_new_data(vol_uuid, 16)); + + /* create basic request */ + request = tss_request_new(NULL); + if (request == NULL) { + error("ERROR: Unable to create TSS request\n"); + plist_free(parameters); + return -1; + } + + /* add common tags from manifest */ + if (tss_request_add_local_policy_tags(request, parameters) < 0) { + error("ERROR: Unable to add common tags to TSS request\n"); + plist_free(request); + plist_free(parameters); + return -1; + } + + /* send request and grab response */ + response = tss_request_send(request, client->tss_url); + if (response == NULL) { + info("ERROR: Unable to send TSS request\n"); + plist_free(request); + plist_free(parameters); + return -1; + } + + info("Received SHSH blobs\n"); + + plist_free(request); + plist_free(parameters); + + *tss = response; + + return 0; +} + +int get_local_policy_tss_response(struct idevicerestore_client_t* client, plist_t build_identity, plist_t* tss) { + plist_t request = NULL; + plist_t response = NULL; + *tss = NULL; + + /* populate parameters */ + plist_t parameters = plist_new_dict(); + plist_dict_set_item(parameters, "ApECID", plist_new_uint(client->ecid)); + plist_dict_set_item(parameters, "Ap,LocalBoot", plist_new_bool(0)); + if (client->nonce) { + plist_dict_set_item(parameters, "ApNonce", plist_new_data((const char*)client->nonce, client->nonce_size)); + } + unsigned char* sep_nonce = NULL; + int sep_nonce_size = 0; + get_sep_nonce(client, &sep_nonce, &sep_nonce_size); + + if (sep_nonce) { + plist_dict_set_item(parameters, "ApSepNonce", plist_new_data((const char*)sep_nonce, sep_nonce_size)); + free(sep_nonce); + } + + plist_dict_set_item(parameters, "ApProductionMode", plist_new_bool(1)); + if (client->image4supported) { + plist_dict_set_item(parameters, "ApSecurityMode", plist_new_bool(1)); + plist_dict_set_item(parameters, "ApSupportsImg4", plist_new_bool(1)); + } else { + plist_dict_set_item(parameters, "ApSupportsImg4", plist_new_bool(0)); + } + + tss_parameters_add_from_manifest(parameters, build_identity); + + // Add Ap,LocalPolicy + uint8_t digest[SHA384_DIGEST_LENGTH]; + SHA384(lpol_file, lpol_file_length, digest); + plist_t lpol = plist_new_dict(); + plist_dict_set_item(lpol, "Digest", plist_new_data(digest, SHA384_DIGEST_LENGTH)); + plist_dict_set_item(lpol, "Trusted", plist_new_bool(1)); + plist_dict_set_item(parameters, "Ap,LocalPolicy", lpol); + + // Add Ap,NextStageIM4MHash + // Get previous TSS ticket + uint8_t* ticket = NULL; + uint32_t ticket_length = 0; + tss_response_get_ap_img4_ticket(client->tss, &ticket, &ticket_length); + // Hash it and add it as Ap,NextStageIM4MHash + uint8_t hash[SHA384_DIGEST_LENGTH]; + SHA384(ticket, ticket_length, hash); + plist_dict_set_item(parameters, "Ap,NextStageIM4MHash", plist_new_data(hash, SHA384_DIGEST_LENGTH)); + + /* create basic request */ + request = tss_request_new(NULL); + if (request == NULL) { + error("ERROR: Unable to create TSS request\n"); + plist_free(parameters); + return -1; + } + + /* add common tags from manifest */ + if (tss_request_add_local_policy_tags(request, parameters) < 0) { + error("ERROR: Unable to add common tags to TSS request\n"); + plist_free(request); + plist_free(parameters); + return -1; + } + + /* send request and grab response */ + response = tss_request_send(request, client->tss_url); + if (response == NULL) { + info("ERROR: Unable to send TSS request\n"); + plist_free(request); + plist_free(parameters); + return -1; + } + + info("Received SHSH blobs\n"); + + plist_free(request); + plist_free(parameters); + + *tss = response; + + return 0; +} + void fixup_tss(plist_t tss) { plist_t node; diff --git a/src/idevicerestore.h b/src/idevicerestore.h index 65776c3..3d84c89 100644 --- a/src/idevicerestore.h +++ b/src/idevicerestore.h @@ -32,6 +32,8 @@ extern "C" { #include <stdint.h> #include <plist/plist.h> #include <libirecovery.h> +#include <openssl/sha.h> +#include <uuid/uuid.h> // the flag with value 1 is reserved for internal use only. don't use it. #define FLAG_DEBUG (1 << 1) @@ -89,12 +91,24 @@ int is_image4_supported(struct idevicerestore_client_t* client); int get_ap_nonce(struct idevicerestore_client_t* client, unsigned char** nonce, int* nonce_size); int get_sep_nonce(struct idevicerestore_client_t* client, unsigned char** nonce, int* nonce_size); int get_tss_response(struct idevicerestore_client_t* client, plist_t build_identity, plist_t* tss); +int get_local_policy_tss_response(struct idevicerestore_client_t* client, plist_t build_identity, plist_t* tss); +int get_recoveryos_root_ticket_tss_response(struct idevicerestore_client_t* client, plist_t build_identity, plist_t* tss); +int get_recovery_os_local_policy_tss_response( + struct idevicerestore_client_t* client, + plist_t build_identity, + plist_t* tss, + plist_t args); void fixup_tss(plist_t tss); int build_manifest_get_identity_count(plist_t build_manifest); int build_manifest_check_compatibility(plist_t build_manifest, const char* product); void build_manifest_get_version_information(plist_t build_manifest, struct idevicerestore_client_t* client); plist_t build_manifest_get_build_identity_for_model(plist_t build_manifest, const char *hardware_model); plist_t build_manifest_get_build_identity_for_model_with_restore_behavior(plist_t build_manifest, const char *hardware_model, const char *behavior); +plist_t build_manifest_get_build_identity_for_model_with_restore_behavior_and_global_signing( + plist_t build_manifest, + const char *hardware_model, + const char *behavior, + uint8_t global_signing); int build_manifest_get_build_count(plist_t build_manifest); void build_identity_print_information(plist_t build_identity); int build_identity_check_components_in_ipsw(plist_t build_identity, const char* ipsw); @@ -35,7 +35,7 @@ #include "endianness.h" -#define TSS_CLIENT_VERSION_STRING "libauthinstall-698.0.5" +#define TSS_CLIENT_VERSION_STRING "libauthinstall-776.60.1" #define ECID_STRSIZE 0x20 typedef struct { @@ -58,7 +58,7 @@ plist_t tss_request_new(plist_t overrides) { plist_t request = plist_new_dict(); - plist_dict_set_item(request, "@Locality", plist_new_string("en_US")); + plist_dict_set_item(request, "@BBTicket", plist_new_bool(1)); plist_dict_set_item(request, "@HostPlatformInfo", #ifdef WIN32 plist_new_string("windows") @@ -82,6 +82,116 @@ plist_t tss_request_new(plist_t overrides) { return request; } +int tss_request_add_local_policy_tags(plist_t request, plist_t parameters) +{ + plist_t node = NULL; + + plist_dict_set_item(request, "@ApImg4Ticket", plist_new_bool(1)); + + /* Ap,LocalBoot */ + node = plist_dict_get_item(parameters, "Ap,LocalBoot"); + if (!node || plist_get_node_type(node) != PLIST_BOOLEAN) { + error("ERROR: Unable to find required Ap,LocalBoot in parameters\n"); + return -1; + } + plist_dict_set_item(request, "Ap,LocalBoot", plist_copy(node)); + node = NULL; + + /* Ap,LocalPolicy */ + node = plist_dict_get_item(parameters, "Ap,LocalPolicy"); + if (!node || plist_get_node_type(node) != PLIST_DICT) { + error("ERROR: Unable to find required Ap,LocalPolicy in parameters\n"); + return -1; + } + plist_dict_set_item(request, "Ap,LocalPolicy", plist_copy(node)); + node = NULL; + + /* Ap,NextStageIM4MHash */ + node = plist_dict_get_item(parameters, "Ap,NextStageIM4MHash"); + if (!node || plist_get_node_type(node) != PLIST_DATA) { + error("ERROR: Unable to find required Ap,NextStageIM4MHash in parameters\n"); + return -1; + } + plist_dict_set_item(request, "Ap,NextStageIM4MHash", plist_copy(node)); + node = NULL; + + /* Ap,RecoveryOSPolicyNonceHash */ + node = plist_dict_get_item(parameters, "Ap,RecoveryOSPolicyNonceHash"); + if (node) { + plist_dict_set_item(request, "Ap,RecoveryOSPolicyNonceHash", plist_copy(node)); + } + node = NULL; + + /* Ap,VolumeUUID */ + node = plist_dict_get_item(parameters, "Ap,VolumeUUID"); + if (node) { + plist_dict_set_item(request, "Ap,VolumeUUID", plist_copy(node)); + } + node = NULL; + + /* ApECID */ + node = plist_dict_get_item(parameters, "ApECID"); + if (node) { + plist_dict_set_item(request, "ApECID", plist_copy(node)); + } + node = NULL; + + /* ApChipID */ + node = plist_dict_get_item(parameters, "ApChipID"); + if (node) { + plist_dict_set_item(request, "ApChipID", plist_copy(node)); + } + node = NULL; + + /* ApBoardID */ + node = plist_dict_get_item(parameters, "ApBoardID"); + if (node) { + plist_dict_set_item(request, "ApBoardID", plist_copy(node)); + } + node = NULL; + + /* ApSecurityDomain */ + node = plist_dict_get_item(parameters, "ApSecurityDomain"); + if (node) { + plist_dict_set_item(request, "ApSecurityDomain", plist_copy(node)); + } + node = NULL; + + /* ApNonce */ + node = plist_dict_get_item(parameters, "ApNonce"); + if (node) { + plist_dict_set_item(request, "ApNonce", plist_copy(node)); + } + node = NULL; + + /* ApSecurityMode */ + node = plist_dict_get_item(request, "ApSecurityMode"); + if (!node) { + /* copy from parameters if available */ + node = plist_dict_get_item(parameters, "ApSecurityMode"); + if (!node || plist_get_node_type(node) != PLIST_BOOLEAN) { + error("ERROR: Unable to find required ApSecurityMode in parameters\n"); + return -1; + } + plist_dict_set_item(request, "ApSecurityMode", plist_copy(node)); + node = NULL; + } + + node = plist_dict_get_item(request, "ApProductionMode"); + if (!node) { + /* ApProductionMode */ + node = plist_dict_get_item(parameters, "ApProductionMode"); + if (!node || plist_get_node_type(node) != PLIST_BOOLEAN) { + error("ERROR: Unable to find required ApProductionMode in parameters\n"); + return -1; + } + plist_dict_set_item(request, "ApProductionMode", plist_copy(node)); + node = NULL; + } + + return 0; +} + int tss_parameters_add_from_manifest(plist_t parameters, plist_t build_identity) { plist_t node = NULL; @@ -96,6 +206,12 @@ int tss_parameters_add_from_manifest(plist_t parameters, plist_t build_identity) plist_dict_set_item(parameters, "UniqueBuildID", plist_copy(node)); node = NULL; + /* Ap,OSLongVersion */ + node = plist_dict_get_item(build_identity, "Ap,OSLongVersion"); + if (node) { + plist_dict_set_item(parameters, "Ap,OSLongVersion", plist_copy(node)); + } + /* ApChipID */ int chip_id = 0; node = plist_dict_get_item(build_identity, "ApChipID"); @@ -359,6 +475,12 @@ int tss_request_add_ap_img4_tags(plist_t request, plist_t parameters) { return -1; } + /* Ap,OSLongVersion */ + node = plist_dict_get_item(parameters, "Ap,OSLongVersion"); + if (node) { + plist_dict_set_item(request, "Ap,OSLongVersion", plist_copy(node)); + } + /* ApNonce */ node = plist_dict_get_item(parameters, "ApNonce"); if (!node || plist_get_node_type(node) != PLIST_DATA) { @@ -594,7 +716,7 @@ static void tss_entry_apply_restore_request_rules(plist_t tss_entry, plist_t par } } -int tss_request_add_ap_tags(plist_t request, plist_t parameters, plist_t overrides) { +int tss_request_add_ap_recovery_tags(plist_t request, plist_t parameters, plist_t overrides) { /* loop over components from build manifest */ plist_t manifest_node = plist_dict_get_item(parameters, "Manifest"); if (!manifest_node || plist_get_node_type(manifest_node) != PLIST_DICT) { @@ -622,6 +744,120 @@ int tss_request_add_ap_tags(plist_t request, plist_t parameters, plist_t overrid continue; } + // Compared to ac2, not needed for RecoveryOSRootTicket + if ((strcmp(key, "SE,UpdatePayload") == 0)) { + free(key); + continue; + } + if ((strcmp(key, "BaseSystem") == 0)) { + free(key); + continue; + } + if ((strcmp(key, "ANS") == 0)) { + free(key); + continue; + } + if ((strcmp(key, "Ap,AudioBootChime") == 0)) { + free(key); + continue; + } + if ((strcmp(key, "Ap,CIO") == 0)) { + free(key); + continue; + } + if ((strcmp(key, "Ap,RestoreCIO") == 0)) { + free(key); + continue; + } + if ((strcmp(key, "Ap,RestoreTMU") == 0)) { + free(key); + continue; + } + if ((strcmp(key, "Ap,TMU") == 0)) { + free(key); + continue; + } + if ((strcmp(key, "Ap,rOSLogo1") == 0)) { + free(key); + continue; + } + if ((strcmp(key, "Ap,rOSLogo2") == 0)) { + free(key); + continue; + } + if ((strcmp(key, "AppleLogo") == 0)) { + free(key); + continue; + } + if ((strcmp(key, "DCP") == 0)) { + free(key); + continue; + } + if ((strcmp(key, "LLB") == 0)) { + free(key); + continue; + } + if ((strcmp(key, "RecoveryMode") == 0)) { + free(key); + continue; + } + if ((strcmp(key, "RestoreANS") == 0)) { + free(key); + continue; + } + if ((strcmp(key, "RestoreDCP") == 0)) { + free(key); + continue; + } + if ((strcmp(key, "RestoreDeviceTree") == 0)) { + free(key); + continue; + } + if ((strcmp(key, "RestoreKernelCache") == 0)) { + free(key); + continue; + } + if ((strcmp(key, "RestoreLogo") == 0)) { + free(key); + continue; + } + if ((strcmp(key, "RestoreRamDisk") == 0)) { + free(key); + continue; + } + if ((strcmp(key, "RestoreSEP") == 0)) { + free(key); + continue; + } + if ((strcmp(key, "SEP") == 0)) { + free(key); + continue; + } + if ((strcmp(key, "ftap") == 0)) { + free(key); + continue; + } + if ((strcmp(key, "ftsp") == 0)) { + free(key); + continue; + } + if ((strcmp(key, "iBEC") == 0)) { + free(key); + continue; + } + if ((strcmp(key, "iBSS") == 0)) { + free(key); + continue; + } + if ((strcmp(key, "rfta") == 0)) { + free(key); + continue; + } + if ((strcmp(key, "rfts") == 0)) { + free(key); + continue; + } + /* FIXME: only used with diagnostics firmware */ if (strcmp(key, "Diags") == 0) { free(key); @@ -629,11 +865,114 @@ int tss_request_add_ap_tags(plist_t request, plist_t parameters, plist_t overrid } if (_plist_dict_get_bool(parameters, "_OnlyFWComponents")) { + if (!_plist_dict_get_bool(manifest_entry, "Trusted")) { + debug("DEBUG: %s: Skipping '%s' as it is not trusted", __func__, key); + continue; + } + plist_t info_dict = plist_dict_get_item(manifest_entry, "Info"); + if (!_plist_dict_get_bool(info_dict, "IsFirmwarePayload") && !_plist_dict_get_bool(info_dict, "IsSecondaryFirmwarePayload") && !_plist_dict_get_bool(info_dict, "IsFUDFirmware")) { + debug("DEBUG: %s: Skipping '%s' as it is neither firmware nor secondary nor FUD firmware payload\n", __func__, key); + continue; + } + } + + /* copy this entry */ + plist_t tss_entry = plist_copy(manifest_entry); + + // ac2 TSS recoveryOSRootTicket needs EPRO and ESEC to be true + plist_dict_set_item(tss_entry, "EPRO", plist_new_bool(1)); + plist_dict_set_item(tss_entry, "ESEC", plist_new_bool(1)); + + /* remove obsolete Info node */ + plist_dict_remove_item(tss_entry, "Info"); + + /* handle RestoreRequestRules */ + plist_t rules = plist_access_path(manifest_entry, 2, "Info", "RestoreRequestRules"); + if (rules) { + debug("DEBUG: Applying restore request rules for entry %s\n", key); + tss_entry_apply_restore_request_rules(tss_entry, parameters, rules); + } + + /* Make sure we have a Digest key for Trusted items even if empty */ + plist_t node = plist_dict_get_item(manifest_entry, "Trusted"); + if (node && plist_get_node_type(node) == PLIST_BOOLEAN) { + uint8_t trusted; + plist_get_bool_val(node, &trusted); + if (trusted && !plist_access_path(manifest_entry, 1, "Digest")) { + debug("DEBUG: No Digest data, using empty value for entry %s\n", key); + plist_dict_set_item(tss_entry, "Digest", plist_new_data(NULL, 0)); + } + } + + /* finally add entry to request */ + plist_dict_set_item(request, key, tss_entry); + + free(key); + } + free(iter); + + /* apply overrides */ + if (overrides) { + plist_dict_merge(&request, overrides); + } + + return 0; +} + +int tss_request_add_ap_tags(plist_t request, plist_t parameters, plist_t overrides) { + /* loop over components from build manifest */ + plist_t manifest_node = plist_dict_get_item(parameters, "Manifest"); + if (!manifest_node || plist_get_node_type(manifest_node) != PLIST_DICT) { + error("ERROR: Unable to find restore manifest\n"); + return -1; + } + + /* add components to request */ + char* key = NULL; + plist_t manifest_entry = NULL; + plist_dict_iter iter = NULL; + plist_dict_new_iter(manifest_node, &iter); + while (1) { + plist_dict_next_item(manifest_node, iter, &key, &manifest_entry); + if (key == NULL) + break; + if (!manifest_entry || plist_get_node_type(manifest_entry) != PLIST_DICT) { + error("ERROR: Unable to fetch BuildManifest entry\n"); + return -1; + } + + /* do not populate BaseBandFirmware, only in basebaseband request */ + if ((strcmp(key, "BasebandFirmware") == 0)) { + free(key); + continue; + } + + // Compared to ac2, not needed + if ((strcmp(key, "SE,UpdatePayload") == 0)) { + free(key); + continue; + } + + // Compared to ac2, not needed + if ((strcmp(key, "BaseSystem") == 0)) { + free(key); + continue; + } + + /* FIXME: only used with diagnostics firmware */ + if (strcmp(key, "Diags") == 0) { + free(key); + continue; + } + + if (_plist_dict_get_bool(parameters, "_OnlyFWComponents")) { if (!_plist_dict_get_bool(manifest_entry, "Trusted")) { debug("DEBUG: %s: Skipping '%s' as it is not trusted", __func__, key); continue; } + + plist_t info_dict = plist_dict_get_item(manifest_entry, "Info"); if (!_plist_dict_get_bool(info_dict, "IsFirmwarePayload") && !_plist_dict_get_bool(info_dict, "IsSecondaryFirmwarePayload") && !_plist_dict_get_bool(info_dict, "IsFUDFirmware")) { debug("DEBUG: %s: Skipping '%s' as it is neither firmware nor secondary nor FUD firmware payload\n", __func__, key); continue; @@ -36,8 +36,10 @@ int tss_parameters_add_from_manifest(plist_t parameters, plist_t build_identity) /* request */ plist_t tss_request_new(plist_t overrides); +int tss_request_add_local_policy_tags(plist_t request, plist_t parameters); int tss_request_add_common_tags(plist_t request, plist_t parameters, plist_t overrides); int tss_request_add_ap_tags(plist_t request, plist_t parameters, plist_t overrides); +int tss_request_add_ap_recovery_tags(plist_t request, plist_t parameters, plist_t overrides); int tss_request_add_baseband_tags(plist_t request, plist_t parameters, plist_t overrides); int tss_request_add_se_tags(plist_t request, plist_t parameters, plist_t overrides); int tss_request_add_savage_tags(plist_t request, plist_t parameters, plist_t overrides, char **component_name); |