summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--configure.ac3
-rw-r--r--src/common.h2
-rw-r--r--src/idevicerestore.c346
-rw-r--r--src/idevicerestore.h14
-rw-r--r--src/tss.c345
-rw-r--r--src/tss.h2
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);
diff --git a/src/tss.c b/src/tss.c
index fecfd0f..4881343 100644
--- a/src/tss.c
+++ b/src/tss.c
@@ -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;
diff --git a/src/tss.h b/src/tss.h
index 85ade57..86dce42 100644
--- a/src/tss.h
+++ b/src/tss.h
@@ -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);