diff --git a/.gitignore b/.gitignore index 245a6c54..49cdabad 100644 --- a/.gitignore +++ b/.gitignore @@ -1,31 +1,26 @@ -*.patch +*.DS_Store +.patch *.diff +*/.libs +*/.deps +*.a +*.o +*.la +*.lo .*.swp -Makefile -Makefile.in +*Makefile* aclocal.m4 autom4te.cache -depcomp compile -config.h -config.h.in -config.log -config.status -config.guess -config.sub +config.* configure +depcomp install-sh libtool ltmain.sh m4 missing -tsschecker/all_tsschecker.h -tsschecker/*.a -tsschecker/*.o -tsschecker/*.la -tsschecker/*.lo -tsschecker/tsschecker -tsschecker/tsschecker.exe -tsschecker/.libs -tsschecker/.deps +*/all.h.bak +*/tsschecker +*/tsschecker.exe stamp-h1 diff --git a/LICENSE b/LICENSE.txt similarity index 100% rename from LICENSE rename to LICENSE.txt diff --git a/Makefile.am b/Makefile.am index b2075c20..200089d5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1 +1 @@ -SUBDIRS = tsschecker +SUBDIRS = tsschecker \ No newline at end of file diff --git a/Makefile.static b/Makefile.static deleted file mode 100644 index 77ff68e2..00000000 --- a/Makefile.static +++ /dev/null @@ -1,22 +0,0 @@ -TARGET = tsschecker_tool -INSTALLTARGET = tsschecker -CFLAGS += -Wall -std=c11 -LDFLAGS += -l:libplist.a -l:libxml2.a -l:liblzma.a -l:libfragmentzip.a -lcurl -lm -lcrypto -lz -SRC_DIR += tsschecker -OBJECTS += $(SRC_DIR)/main.o $(SRC_DIR)/download.o $(SRC_DIR)/jsmn.o $(SRC_DIR)/tss.o $(SRC_DIR)/tsschecker.o - - -all : $(TARGET) - -$(TARGET) : $(OBJECTS) - $(CC) $(CFLAGS) $(OBJECTS) $(LDFLAGS) -o $(TARGET) - @echo "Successfully built $(TARGET)" - -$(SRC_DIR)/%.o : $(SRC_DIR)/%.c - $(CC) $(CFLAGS) $< -c -o $@ - -install : $(TARGET) - cp $(TARGET) /usr/local/bin/$(INSTALLTARGET) - @echo "Installed $(INSTALLTARGET)" -clean : - rm -rf tsschecker/*.o $(TARGET) diff --git a/README.md b/README.md deleted file mode 100644 index f06c39af..00000000 --- a/README.md +++ /dev/null @@ -1,56 +0,0 @@ -# tsschecker -_tsschecker is a powerful tool to check tss signing status of various devices and iOS versions._ - -Latest compiled version can be found here: -(macOS & Windows) -https://github.com/encounter/tsschecker/releases - -## Features -* Allows you to get lists of all devices and all iOS/OTA versions for a specific device. -* Can check signing status for default iOS versions and beta ipsws (by specifying a `BuildManifest.plist`) -* Works without specifying any device relevant values to check signing status, but can be used to save blobs when given an ECID and the option `--print-tss-response` (although there are better tools to do this). - -tsschecker is not only meant to be used to check signing status, but also to explore Apple's tss servers. -By using all of its customization possibilities, you might discover a combination of devices and iOS versions that is now getting signed but wasn't getting signed before. - -# Dependencies -* ## Bundled Libs - Those don't need to be installed manually - * [tss](https://github.com/libimobiledevice) -* ## External Libs - Make sure these are installed - * [libcurl](https://curl.haxx.se/libcurl/) - * [libplist](https://github.com/libimobiledevice/libplist) - * [libfragmentzip](https://github.com/tihmstar/libfragmentzip) -* ## Submodules - Make sure these projects compile on your system - * [jssy](https://github.com/tihmstar/jssy) - - -## tsschecker help -_(might become outdated):_ - -Usage: `tsschecker [OPTIONS]` - -| option (short) | option (long) | description | -|----------------|---------------------------|-----------------------------------------------------------------------------------| -| `-d` | `--device MODEL` | specify device by its MODEL (eg. `iPhone4,1`) | -| `-i` | `--ios VERSION` | specify iOS version (eg. `6.1.3`) | -| | `--buildid BUILDID` | specific buildid instead of iOS version (eg. `13C75`) | -| | `--boardconfig BOARD` | specific boardconfig instead of iPhone model (eg. `n61ap`) | -| `-h` | `--help` | prints usage information | -| `-o` | `--ota` | check OTA signing status, instead of normal restore | -| `-b` | `--no-baseband` | don't check baseband signing status. Request a ticket without baseband | -| `-m` |`--build-manifest MANIFEST`| manually specify buildmanifest. (can be used with `-d`) | -| `-s` | `--save` | save fetched shsh blobs (mostly makes sense with -e) | -| `-l` | `--latest` | use latest public iOS version instead of manually specifying one
especially useful with `-s` and `-e` for saving blobs | -| | `--apnonce NONCE` | manually specify APNONCE instead of using random one (not required for saving blobs)| -| | `--sepnonce NONCE` | manually specify SEPNONCE instead of using random one (not required for saving blobs) | -| | `--save-path PATH` | specify path for saving blobs | -| `-e`  | `--ecid ECID` | manually specify an ECID to be used for fetching blobs, instead of using random ones.
ECID must be either dec or hex eg. `5482657301265` or `ab46efcbf71` | -| | `--beta` | request ticket for beta instead of normal release (use with `-o`) | -| | `--list-devices` | list all known devices | -| |`--list-ios` | list all known iOS versions | -| |`--nocache` | ignore caches and re-download required files | -| |`--print-tss-request` | prints tss request that will be sent (plist) | -| |`--print-tss-response` | prints tss response that come from Apple (plist) | diff --git a/ReadMe.md b/ReadMe.md new file mode 100644 index 00000000..5e9fc10b --- /dev/null +++ b/ReadMe.md @@ -0,0 +1,44 @@ +# tsschecker +_tsschecker is a powerful tool to work with signing technology on iOS/tvOS/watchOS devices._ + +Latest compiled version can be found [here](https://github.com/s0uthwest/tsschecker/releases). Windows & Linux version are supported, but I won't compile it. + +## Features +* Allows you to get lists of all iOS/tvOS/watchOS versions for a specific device. +* Can check signing status for default iOS/tvOS/watchOS versions. +* Works without specifying any device relevant values to check signing status, but can be used to save signing tickets when given an ECID and the option `--print-tss-response` (although there are better tools to do this). +* __If you'll want to save signing tickets with recommended ApNonces, please, see [this file](https://github.com/s0uthwest/tsschecker/blob/master/nonces.txt).__ + +tsschecker isn't only meant to be used to check signing status, but also to explore Apple's TSS servers. +By using all of its customization possibilities, you might discover a combination of devices and iOS versions that is now getting signed but wasn't getting signed before. + +# Dependencies +* ## Bundled Libs + * [tss](https://github.com/libimobiledevice); +* ## External Libs + * [libcurl](https://github.com/curl/curl); + * [libplist](https://github.com/libimobiledevice/libplist); + * [libfragmentzip](https://github.com/s0uthwest/libfragmentzip); + * [openssl](https://github.com/openssl/openssl) or commonCrypto on macOS/OS X; + * [libirecovery](https://github.com/s0uthwest/libirecovery); +* ## Submodules + * [jssy](https://github.com/tihmstar/jssy) + +## Compiling & installing +Open terminal and execute the command: `./autogen.sh && make` or use Xcode project. +The easiest way to install on macOS is using [`brew`](https://brew.sh): `brew install stek29/idevice/tsschecker-s0uthwest`. + +### Some about [cURL](https://github.com/curl/curl) +* Linux: Follow [this guide](https://dev.to/jake/using-libcurl3-and-libcurl4-on-ubuntu-1804-bionic-184g) to use tsschecker on Ubuntu 18.04 (Bionic) as it requires libcurl3 which cannot coexist with libcurl4 on this OS. +* macOS: open file [Makefile.am](https://github.com/s0uthwest/tsschecker/blob/master/tsschecker/Makefile.am) and update line with LDADD: `tsschecker_LDADD = $(AM_LDFLAGS) libjssy.a /usr/lib/libcurl.4.dylib` + It required for downloading JSON files from ipsw.me for now. + +## Report an issue +You can do it [here](https://github.com/s0uthwest/tsschecker/issues). + +## Credits +Creator of [original project](https://github.com/tihmstar/tsschecker) - [tihmstar](https://github.com/tihmstar). + + +ReadMe updated on: + 2019-06-19 diff --git a/autogen.sh b/autogen.sh index 4ec16f0b..9a1f8a28 100755 --- a/autogen.sh +++ b/autogen.sh @@ -13,4 +13,3 @@ autoconf if [ -z "$NOCONFIGURE" ]; then ./configure "$@" fi -./setBuildVersion.sh diff --git a/configure.ac b/configure.ac index f38ad840..271033cd 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,5 @@ AC_PREREQ([2.69]) -AC_INIT([tsschecker], [1.0], [https://github.com/encounter/tsschecker/issues],, [https://github.com/encounter/tsschecker]) -# prepare for automake +AC_INIT([tsschecker], [1.0], [https://github.com/s0uthwest/tsschecker/issues]) AM_INIT_AUTOMAKE([foreign]) AC_CONFIG_SRCDIR([tsschecker/tsschecker.h]) @@ -11,11 +10,13 @@ AC_PROG_CC CFLAGS+=" -std=c11" AC_PROG_INSTALL AC_PROG_LIBTOOL - AC_CONFIG_MACRO_DIRS([m4]) -# Checks for libraries. +# Version bump +CFLAGS+=" -D TSSCHECKER_VERSION_COUNT=\\\"$(git rev-list --count HEAD | tr -d '\n')\\\"" +CFLAGS+=" -D TSSCHECKER_VERSION_SHA=\\\"$(git rev-parse HEAD | tr -d '\n')\\\"" +# Checks for libraries. AC_CANONICAL_HOST AC_ARG_WITH( @@ -35,14 +36,13 @@ AC_ARG_WITH( ) PKG_CHECK_MODULES(libplist, libplist >= 1.0) -PKG_CHECK_MODULES(libcurl, libcurl >= 1.0) +PKG_CHECK_MODULES(curl, libcurl >= 1.0) PKG_CHECK_MODULES(libfragmentzip, libfragmentzip >= 1.0) AS_IF([test "x$with_libcrypto" != xno], [PKG_CHECK_MODULES(libcrypto, libcrypto >= 1.0)] ) PKG_CHECK_MODULES(libirecovery, libirecovery >= 0.2.0) - # Checks for header files. AC_CHECK_HEADERS([stddef.h stdlib.h string.h unistd.h]) @@ -85,4 +85,3 @@ AM_CONDITIONAL(WIN32, test x$win32 = xtrue) AC_CONFIG_FILES([Makefile tsschecker/Makefile]) AC_OUTPUT - diff --git a/devices.txt b/devices.txt deleted file mode 100644 index c9bd370e..00000000 --- a/devices.txt +++ /dev/null @@ -1,4 +0,0 @@ -iPhone8,2-n66ap 123456789 -iPhone7,2 123456789 -iPhone6,2 123456789 :603be133ff0bdfa0f83f21e74191cf6770ea43bb:352dfad1713834f4f94c5ff3c3e5e99477347b95:42c88f5a7b75bc944c288a7215391dc9c73b6e9f:0dc448240696866b0cc1b2ac3eca4ce22af11cb3:9804d99e85bbafd4bb1135a1044773b4df9f1ba3 - diff --git a/external/jssy b/external/jssy index ba625644..e17d3c8e 160000 --- a/external/jssy +++ b/external/jssy @@ -1 +1 @@ -Subproject commit ba6256448344799247d2c858cf2db879e62043f6 +Subproject commit e17d3c8ec5216692efbbe59bbe9801bb7661e07d diff --git a/saveblobs.sh b/saveblobs.sh deleted file mode 100644 index 5f18e454..00000000 --- a/saveblobs.sh +++ /dev/null @@ -1,65 +0,0 @@ -#!/bin/bash -cd /var/shsh -declare -a DIRS=("shsh" "shsh_ota" "shsh_beta_ota") -for dir in "${DIRS[@]}" -do - mkdir $dir 2>/dev/null -done - -rm /tmp/ota.json 2>/dev/null -rm /tmp/firmware.json 2>/dev/null -rm /tmp/bbgcid.json 2>/dev/null - -while read device; do - if [ -z "$device" ]; then - continue - fi - modelWithBoard=$(echo $device | cut -d ' ' -f 1) - model=$(echo $modelWithBoard | cut -d '-' -f 1) - board=$(echo $modelWithBoard | cut -d '-' -f 2) - ecid=$(echo $device | cut -d ' ' -f 2) - - i=2 - ap="" - sp="" - hw="" - - if [ "$board" != "$model" ] && [ -n "$board" ]; then - hw="--boardconfig $board" - fi - - cnt="true"; - while [ "$cnt" == "true" ]; - do - cnt="false" - apnonce=$(echo $device | cut -d ':' -f $i) - apn="" - sp="" - if [ "$apnonce" != "$device" ] && [ -n "$apnonce" ]; then - apn=$apnonce - sp="/$apnonce" - ap="--apnonce $apnonce" - i=$(($i+1)) - mkdir "shsh$sp" 2>/dev/null - cnt="true" - fi - - echo saving blobs for $modelWithBoard $ecid $apn - echo -n "saving normal blob ... " - ret=$(tsschecker -d $model -e $ecid -s --save-path "shsh$sp" -l $ap $hw);code=$? - echo "$ret" >>/tmp/tsschecker_saveblobs_fullog.log - echo -n $(echo $ret | grep -o "iOS .* for device" | rev | cut -c 12- | rev ) - if [ $code -eq 0 ]; then echo " ok"; else echo " failed"; echo $ret;fi - done - - echo -n "saving ota blob ... " - ret=$(tsschecker -d $model -e $ecid -s --save-path shsh_ota -l -o $hw);code=$? - echo "$ret" >>/tmp/tsschecker_saveblobs_fullog.log - echo -n $(echo $ret | grep -o "iOS .* for device" | rev | cut -c 12- | rev ) - if [ $code -eq 0 ]; then echo " ok"; else echo " failed"; echo $ret;fi - echo -n "saving beta ota blob ... " - ret=$(tsschecker -d $model -e $ecid -s --save-path shsh_beta_ota -l -o --beta $hw);code=$? - echo "$ret" >>/tmp/tsschecker_saveblobs_fullog.log - echo -n $(echo $ret | grep -o "iOS .* for device" | rev | cut -c 12- | rev ) - if [ $code -eq 0 ]; then echo " ok"; else echo " failed"; echo $ret;fi -done /dev/null || sed -i "s/.*VERSION_COMMIT_COUNT.*/#define VERSION_COMMIT_COUNT \"$(git rev-list --count HEAD)\"/" ./tsschecker/all_tsschecker.h 2>/dev/null -sed -i '.bak' "s/.*VERSION_COMMIT_SHA.*/#define VERSION_COMMIT_SHA \"$(git rev-parse HEAD)\"/" ./tsschecker/all_tsschecker.h 2>/dev/null || sed -i "s/.*VERSION_COMMIT_SHA.*/#define VERSION_COMMIT_SHA \"$(git rev-parse HEAD)\"/" ./tsschecker/all_tsschecker.h 2>/dev/null diff --git a/tsschecker.xcodeproj/project.pbxproj b/tsschecker.xcodeproj/project.pbxproj index 34d11b26..2dc35e87 100644 --- a/tsschecker.xcodeproj/project.pbxproj +++ b/tsschecker.xcodeproj/project.pbxproj @@ -3,17 +3,24 @@ archiveVersion = 1; classes = { }; - objectVersion = 46; + objectVersion = 48; objects = { /* Begin PBXBuildFile section */ - 87B93E861EE709A800709583 /* jssy.c in Sources */ = {isa = PBXBuildFile; fileRef = 87B93E841EE709A800709583 /* jssy.c */; }; - 87CD9A3D1E0F35FE00E566B7 /* libfragmentzip.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 87CD9A3C1E0F35FE00E566B7 /* libfragmentzip.0.dylib */; }; + 56163B0A21E4FCB00069A0B0 /* debug.h in Sources */ = {isa = PBXBuildFile; fileRef = 56163B0921E4FB980069A0B0 /* debug.h */; }; + 5641589521FCC136005C62E9 /* libirecovery.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5641589421FCC135005C62E9 /* libirecovery.a */; }; + 5641589721FCC141005C62E9 /* libcrypto.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5641589621FCC141005C62E9 /* libcrypto.a */; }; + 5641589921FCC14E005C62E9 /* libfragmentzip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5641589821FCC14E005C62E9 /* libfragmentzip.a */; }; + 5641589B21FCC15B005C62E9 /* libplist.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 5641589A21FCC15A005C62E9 /* libplist.a */; }; + 56520C1421B2693F005BD3F7 /* jssy.c in Sources */ = {isa = PBXBuildFile; fileRef = 56520C0C21B2693E005BD3F7 /* jssy.c */; }; + 56520C1521B2693F005BD3F7 /* jssy.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 56520C0D21B2693E005BD3F7 /* jssy.cpp */; }; + 56520C1721B2693F005BD3F7 /* cmain.c in Sources */ = {isa = PBXBuildFile; fileRef = 56520C1021B2693F005BD3F7 /* cmain.c */; }; + 56931F5C21D900D200A88574 /* all.h in Sources */ = {isa = PBXBuildFile; fileRef = 563DA62E21BBC58900844624 /* all.h */; }; + 56DA633E21E3412400821A21 /* ptr_smart.hpp in Sources */ = {isa = PBXBuildFile; fileRef = 56520C1221B2693F005BD3F7 /* ptr_smart.hpp */; }; + 56DA633F21E3412900821A21 /* helper.h in Sources */ = {isa = PBXBuildFile; fileRef = 56520C1321B2693F005BD3F7 /* helper.h */; }; + 56EF4C0121B1A2D10056D405 /* libcurl.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 56EF4C0021B1A2D10056D405 /* libcurl.tbd */; }; 87CEC4C91C576BD9006E75FC /* tss.c in Sources */ = {isa = PBXBuildFile; fileRef = 87CEC4C81C576BD9006E75FC /* tss.c */; }; 87EB90A31C2940CD002CEE70 /* main.c in Sources */ = {isa = PBXBuildFile; fileRef = 87EB90A21C2940CD002CEE70 /* main.c */; }; - 87EB90AC1C2940FB002CEE70 /* libplist.3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 87EB90AB1C2940FB002CEE70 /* libplist.3.dylib */; }; - 87EB90AE1C294108002CEE70 /* libcurl.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 87EB90AD1C294108002CEE70 /* libcurl.tbd */; }; - 87F1F6791E168ABE00301726 /* libirecovery.2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 87F1F6781E168ABE00301726 /* libirecovery.2.dylib */; }; 87F927AC1C3E44CE00343510 /* tsschecker.c in Sources */ = {isa = PBXBuildFile; fileRef = 87F927AA1C3E44CE00343510 /* tsschecker.c */; }; 87F927AF1C3E455200343510 /* download.c in Sources */ = {isa = PBXBuildFile; fileRef = 87F927AD1C3E455200343510 /* download.c */; }; /* End PBXBuildFile section */ @@ -31,18 +38,24 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 8747AC521D83006100349BB9 /* libcrypto.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libcrypto.dylib; path = usr/lib/libcrypto.dylib; sourceTree = SDKROOT; }; - 87AD68BB1D8ACE7F0094A99F /* all_tsschecker.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = all_tsschecker.h; sourceTree = ""; }; - 87B93E841EE709A800709583 /* jssy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jssy.c; path = external/jssy/jssy/jssy.c; sourceTree = SOURCE_ROOT; }; - 87B93E851EE709A800709583 /* jssy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jssy.h; path = external/jssy/jssy/jssy.h; sourceTree = SOURCE_ROOT; }; - 87CD9A3C1E0F35FE00E566B7 /* libfragmentzip.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libfragmentzip.0.dylib; path = ../../../../usr/local/lib/libfragmentzip.0.dylib; sourceTree = ""; }; + 56163B0921E4FB980069A0B0 /* debug.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = debug.h; sourceTree = ""; }; + 563DA62E21BBC58900844624 /* all.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = all.h; sourceTree = ""; }; + 5641589421FCC135005C62E9 /* libirecovery.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libirecovery.a; path = ../../../../../usr/local/lib/libirecovery.a; sourceTree = ""; }; + 5641589621FCC141005C62E9 /* libcrypto.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libcrypto.a; path = ../../../../../usr/local/lib/libcrypto.a; sourceTree = ""; }; + 5641589821FCC14E005C62E9 /* libfragmentzip.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libfragmentzip.a; path = ../../../../../usr/local/lib/libfragmentzip.a; sourceTree = ""; }; + 5641589A21FCC15A005C62E9 /* libplist.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libplist.a; path = ../../../../../usr/local/lib/libplist.a; sourceTree = ""; }; + 56520C0C21B2693E005BD3F7 /* jssy.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = jssy.c; path = external/jssy/jssy/jssy.c; sourceTree = SOURCE_ROOT; }; + 56520C0D21B2693E005BD3F7 /* jssy.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = jssy.cpp; path = external/jssy/jssy/jssy.cpp; sourceTree = SOURCE_ROOT; }; + 56520C0E21B2693E005BD3F7 /* jssy.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = jssy.h; path = external/jssy/jssy/jssy.h; sourceTree = SOURCE_ROOT; }; + 56520C1021B2693F005BD3F7 /* cmain.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cmain.c; path = external/jssy/jssy/cmain.c; sourceTree = SOURCE_ROOT; }; + 56520C1121B2693F005BD3F7 /* jssy.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = jssy.hpp; path = external/jssy/jssy/jssy.hpp; sourceTree = SOURCE_ROOT; }; + 56520C1221B2693F005BD3F7 /* ptr_smart.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; name = ptr_smart.hpp; path = external/jssy/jssy/ptr_smart.hpp; sourceTree = SOURCE_ROOT; }; + 56520C1321B2693F005BD3F7 /* helper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = helper.h; path = external/jssy/jssy/helper.h; sourceTree = SOURCE_ROOT; }; + 56EF4C0021B1A2D10056D405 /* libcurl.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcurl.tbd; path = usr/lib/libcurl.tbd; sourceTree = SDKROOT; }; 87CEC4C81C576BD9006E75FC /* tss.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tss.c; sourceTree = ""; }; 87CEC4CA1C576BE0006E75FC /* tss.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = tss.h; sourceTree = ""; }; 87EB909F1C2940CD002CEE70 /* tsschecker */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = tsschecker; sourceTree = BUILT_PRODUCTS_DIR; }; 87EB90A21C2940CD002CEE70 /* main.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = main.c; sourceTree = ""; }; - 87EB90AB1C2940FB002CEE70 /* libplist.3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libplist.3.dylib; path = ../../../../../usr/local/lib/libplist.3.dylib; sourceTree = ""; }; - 87EB90AD1C294108002CEE70 /* libcurl.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libcurl.tbd; path = usr/lib/libcurl.tbd; sourceTree = SDKROOT; }; - 87F1F6781E168ABE00301726 /* libirecovery.2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libirecovery.2.dylib; path = ../../../../usr/local/lib/libirecovery.2.dylib; sourceTree = ""; }; 87F927AA1C3E44CE00343510 /* tsschecker.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tsschecker.c; sourceTree = ""; }; 87F927AB1C3E44CE00343510 /* tsschecker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tsschecker.h; sourceTree = ""; }; 87F927AD1C3E455200343510 /* download.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = download.c; sourceTree = ""; }; @@ -54,10 +67,11 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 87F1F6791E168ABE00301726 /* libirecovery.2.dylib in Frameworks */, - 87CD9A3D1E0F35FE00E566B7 /* libfragmentzip.0.dylib in Frameworks */, - 87EB90AE1C294108002CEE70 /* libcurl.tbd in Frameworks */, - 87EB90AC1C2940FB002CEE70 /* libplist.3.dylib in Frameworks */, + 5641589721FCC141005C62E9 /* libcrypto.a in Frameworks */, + 5641589B21FCC15B005C62E9 /* libplist.a in Frameworks */, + 5641589521FCC136005C62E9 /* libirecovery.a in Frameworks */, + 5641589921FCC14E005C62E9 /* libfragmentzip.a in Frameworks */, + 56EF4C0121B1A2D10056D405 /* libcurl.tbd in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -75,8 +89,13 @@ 87B93E831EE7099A00709583 /* jssy */ = { isa = PBXGroup; children = ( - 87B93E851EE709A800709583 /* jssy.h */, - 87B93E841EE709A800709583 /* jssy.c */, + 56520C1021B2693F005BD3F7 /* cmain.c */, + 56520C1321B2693F005BD3F7 /* helper.h */, + 56520C0C21B2693E005BD3F7 /* jssy.c */, + 56520C0D21B2693E005BD3F7 /* jssy.cpp */, + 56520C0E21B2693E005BD3F7 /* jssy.h */, + 56520C1121B2693F005BD3F7 /* jssy.hpp */, + 56520C1221B2693F005BD3F7 /* ptr_smart.hpp */, ); name = jssy; sourceTree = ""; @@ -84,8 +103,11 @@ 87CD9A3B1E0F35FE00E566B7 /* Frameworks */ = { isa = PBXGroup; children = ( - 87F1F6781E168ABE00301726 /* libirecovery.2.dylib */, - 87CD9A3C1E0F35FE00E566B7 /* libfragmentzip.0.dylib */, + 56EF4C0021B1A2D10056D405 /* libcurl.tbd */, + 5641589421FCC135005C62E9 /* libirecovery.a */, + 5641589621FCC141005C62E9 /* libcrypto.a */, + 5641589821FCC14E005C62E9 /* libfragmentzip.a */, + 5641589A21FCC15A005C62E9 /* libplist.a */, ); name = Frameworks; sourceTree = ""; @@ -102,9 +124,6 @@ 87EB90961C2940CD002CEE70 = { isa = PBXGroup; children = ( - 8747AC521D83006100349BB9 /* libcrypto.dylib */, - 87EB90AD1C294108002CEE70 /* libcurl.tbd */, - 87EB90AB1C2940FB002CEE70 /* libplist.3.dylib */, 87EB90A11C2940CD002CEE70 /* tsschecker */, 87EB90A01C2940CD002CEE70 /* Products */, 87CD9A3B1E0F35FE00E566B7 /* Frameworks */, @@ -122,7 +141,8 @@ 87EB90A11C2940CD002CEE70 /* tsschecker */ = { isa = PBXGroup; children = ( - 87AD68BB1D8ACE7F0094A99F /* all_tsschecker.h */, + 563DA62E21BBC58900844624 /* all.h */, + 56163B0921E4FB980069A0B0 /* debug.h */, 87B93E821EE7098900709583 /* external */, 87CEC4CB1C576BE8006E75FC /* libs */, 87F927AE1C3E455200343510 /* download.h */, @@ -144,6 +164,7 @@ 87EB909B1C2940CD002CEE70 /* Sources */, 87EB909C1C2940CD002CEE70 /* Frameworks */, 87EB909D1C2940CD002CEE70 /* CopyFiles */, + 561C73F1219738750030617C /* Version bump */, ); buildRules = ( ); @@ -160,20 +181,20 @@ 87EB90971C2940CD002CEE70 /* Project object */ = { isa = PBXProject; attributes = { - LastUpgradeCheck = 0720; + LastUpgradeCheck = 1010; ORGANIZATIONNAME = tihmstar; TargetAttributes = { 87EB909E1C2940CD002CEE70 = { CreatedOnToolsVersion = 7.2; + ProvisioningStyle = Automatic; }; }; }; buildConfigurationList = 87EB909A1C2940CD002CEE70 /* Build configuration list for PBXProject "tsschecker" */; - compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + compatibilityVersion = "Xcode 8.0"; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( - en, ); mainGroup = 87EB90961C2940CD002CEE70; productRefGroup = 87EB90A01C2940CD002CEE70 /* Products */; @@ -185,16 +206,43 @@ }; /* End PBXProject section */ +/* Begin PBXShellScriptBuildPhase section */ + 561C73F1219738750030617C /* Version bump */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Version bump"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "sed -i '.bak' \"s/.*TSSCHECKER_VERSION_COMMIT_COUNT.*/#define TSSCHECKER_VERSION_COMMIT_COUNT \\\"$(git rev-list --count HEAD)\\\"/\" ./tsschecker/all.h 2>/dev/null || sed -i \"s/.*TSSCHECKER_VERSION_COMMIT_COUNT.*/#define TSSCHECKER_VERSION_COMMIT_COUNT \\\"$(git rev-list --count HEAD)\\\"/\" ./tsschecker/all.h 2>/dev/null\nsed -i '.bak' \"s/.*TSSCHECKER_VERSION_COMMIT_SHA.*/#define TSSCHECKER_VERSION_COMMIT_SHA \\\"$(git rev-parse HEAD)\\\"/\" ./tsschecker/all.h 2>/dev/null || sed -i \"s/.*TSSCHECKER_VERSION_COMMIT_SHA.*/#define TSSCHECKER_VERSION_COMMIT_SHA \\\"$(git rev-parse HEAD)\\\"/\" ./tsschecker/all.h 2>/dev/null\n"; + }; +/* End PBXShellScriptBuildPhase section */ + /* Begin PBXSourcesBuildPhase section */ 87EB909B1C2940CD002CEE70 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 56520C1721B2693F005BD3F7 /* cmain.c in Sources */, + 56520C1421B2693F005BD3F7 /* jssy.c in Sources */, + 56DA633F21E3412900821A21 /* helper.h in Sources */, 87F927AC1C3E44CE00343510 /* tsschecker.c in Sources */, + 56520C1521B2693F005BD3F7 /* jssy.cpp in Sources */, 87CEC4C91C576BD9006E75FC /* tss.c in Sources */, 87F927AF1C3E455200343510 /* download.c in Sources */, 87EB90A31C2940CD002CEE70 /* main.c in Sources */, - 87B93E861EE709A800709583 /* jssy.c in Sources */, + 56163B0A21E4FCB00069A0B0 /* debug.h in Sources */, + 56931F5C21D900D200A88574 /* all.h in Sources */, + 56DA633E21E3412400821A21 /* ptr_smart.hpp in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -209,13 +257,23 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "-"; @@ -237,10 +295,19 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ( + /usr/local/include, + /opt/local/include, + ); + INSTALL_PATH = /usr/local/bin; + LIBRARY_SEARCH_PATHS = /usr/local/lib; MACOSX_DEPLOYMENT_TARGET = 10.11; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; + PRODUCT_BUNDLE_IDENTIFIER = net.tihmstar.tsschecker; + PRODUCT_NAME = tsschecker; SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = "\"$(SRCROOT)/external/jssy\""; }; name = Debug; }; @@ -252,13 +319,23 @@ CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "-"; @@ -274,9 +351,18 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; + HEADER_SEARCH_PATHS = ( + /usr/local/include, + /opt/local/include, + ); + INSTALL_PATH = /usr/local/bin; + LIBRARY_SEARCH_PATHS = /usr/local/lib; MACOSX_DEPLOYMENT_TARGET = 10.11; MTL_ENABLE_DEBUG_INFO = NO; + PRODUCT_BUNDLE_IDENTIFIER = net.tihmstar.tsschecker; + PRODUCT_NAME = tsschecker; SDKROOT = macosx; + USER_HEADER_SEARCH_PATHS = "\"$(SRCROOT)/external/jssy\""; }; name = Release; }; @@ -284,14 +370,21 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = ""; GCC_PREFIX_HEADER = ""; HEADER_SEARCH_PATHS = ( /usr/local/include, /opt/local/include, ); LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.12; OTHER_CFLAGS = "-std=c11"; + PRODUCT_BUNDLE_IDENTIFIER = net.tihmstar.tsschecker; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + USER_HEADER_SEARCH_PATHS = "\"$(SRCROOT)/external/jssy\""; }; name = Debug; }; @@ -299,14 +392,21 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = YES; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = ""; GCC_PREFIX_HEADER = ""; HEADER_SEARCH_PATHS = ( /usr/local/include, /opt/local/include, ); LIBRARY_SEARCH_PATHS = /usr/local/lib; + MACOSX_DEPLOYMENT_TARGET = 10.12; OTHER_CFLAGS = "-std=c11"; + PRODUCT_BUNDLE_IDENTIFIER = net.tihmstar.tsschecker; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + USER_HEADER_SEARCH_PATHS = "\"$(SRCROOT)/external/jssy\""; }; name = Release; }; diff --git a/tsschecker.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/tsschecker.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 00000000..18d98100 --- /dev/null +++ b/tsschecker.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/tsschecker.xcodeproj/project.xcworkspace/xcuserdata/s0uthwest.xcuserdatad/UserInterfaceState.xcuserstate b/tsschecker.xcodeproj/project.xcworkspace/xcuserdata/s0uthwest.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 00000000..4a963055 Binary files /dev/null and b/tsschecker.xcodeproj/project.xcworkspace/xcuserdata/s0uthwest.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/tsschecker.xcodeproj/xcuserdata/s0uthwest.xcuserdatad/xcschemes/xcschememanagement.plist b/tsschecker.xcodeproj/xcuserdata/s0uthwest.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 00000000..02a11371 --- /dev/null +++ b/tsschecker.xcodeproj/xcuserdata/s0uthwest.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + tsschecker.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/tsschecker/Makefile.am b/tsschecker/Makefile.am index acf75188..dd1a1c9f 100644 --- a/tsschecker/Makefile.am +++ b/tsschecker/Makefile.am @@ -1,5 +1,5 @@ AM_CFLAGS = $(libplist_CFLAGS) $(libfragmentzip_CFLAGS) $(libcurl_CFLAGS) $(libcrypto_CFLAGS) $(libirecovery_CFLAGS) -I$(top_srcdir)/external/libfragmentzip/include -I$(top_srcdir)/external/jssy/jssy/ -AM_LDFLAGS = $(libplist_LIBS) $(libfragmentzip_LIBS) $(libcurl_LIBS) $(libcrypto_LIBS) $(libirecovery_LIBS) -lm +AM_LDFLAGS = $(libplist_LIBS) $(libcurl_LIBS) $(libcrypto_LIBS) $(libirecovery_LIBS) $(libfragmentzip_LIBS) -lm noinst_LIBRARIES = libjssy.a libjssy_a_CFLAGS = $(AM_CFLAGS) @@ -15,11 +15,11 @@ libtsschecker_la_SOURCES = tsschecker.c tss.c download.c libtsschecker_la_CFLAGS = $(AM_CFLAGS) libtsschecker_la_LIBADD = $(AM_LDFLAGS) libjssy.a else -bin_PROGRAMS = tsschecker +bin_PROGRAMS = tsschecker tsschecker_CFLAGS = $(AM_CFLAGS) if WIN32 tsschecker_LDFLAGS = -all-static -static-libgcc -static-libstdc++ $(AM_LDFLAGS) endif tsschecker_LDADD = $(AM_LDFLAGS) libjssy.a -tsschecker_SOURCES = tsschecker.c tss.c download.c main.c +tsschecker_SOURCES = tsschecker.c tss.c download.c main.c endif diff --git a/tsschecker/all.h b/tsschecker/all.h new file mode 100644 index 00000000..295c7711 --- /dev/null +++ b/tsschecker/all.h @@ -0,0 +1,19 @@ +// +// all.h +// tsschecker +// +// Created by tihmstar on 26.01.16. +// Copyright © 2016 tihmstar. All rights reserved. +// + +#ifndef all_h +#define all_h + +// version bump +#ifdef DEBUG // this is for developing with Xcode +#define TSSCHECKER_VERSION_COUNT "Debug" +#define TSSCHECKER_VERSION_SHA "Build: " __DATE__ " " __TIME__ +#else +#endif + +#endif /* all_h */ diff --git a/tsschecker/all_tsschecker.h b/tsschecker/debug.h similarity index 66% rename from tsschecker/all_tsschecker.h rename to tsschecker/debug.h index 424f4af3..d54357bc 100644 --- a/tsschecker/all_tsschecker.h +++ b/tsschecker/debug.h @@ -1,31 +1,27 @@ // -// all.h +// debug.h // tsschecker // -// Created by tihmstar on 26.01.16. -// Copyright © 2016 tihmstar. All rights reserved. +// Created by s0uthwest on 08.01.19. +// Copyright © 2015 tihmstar. All rights reserved. // -#ifndef all_h -#define all_h +#ifndef debug_h +#define debug_h +// idevicerestore flags extern int idevicerestore_debug; - #define info(a ...) printf(a) #define log(a ...) if (dbglog) printf(a) #define warning(a ...) if (dbglog) printf("[WARNING] "), printf(a) #define debug(a ...) if (idevicerestore_debug) printf(a) #define error(a ...) printf("[Error] "),printf(a) -#define VERSION_COMMIT_COUNT "UNDEFINED_COMMIT_COUNT" -#define VERSION_COMMIT_SHA "UNDEFINED_COMMIT_SHA" - - -//statis assert +// statis assert #define CASSERT(predicate, file) _impl_CASSERT_LINE(predicate,__LINE__,file) #define _impl_PASTE(a,b) a##b #define _impl_CASSERT_LINE(predicate, line, file) \ typedef char _impl_PASTE(assertion_failed_##file##_,line)[2*!!(predicate)-1]; -#endif /* all_h */ +#endif /* debug_h */ diff --git a/tsschecker/download.h b/tsschecker/download.h index 52821e6e..0218d285 100644 --- a/tsschecker/download.h +++ b/tsschecker/download.h @@ -10,7 +10,7 @@ #define download_h #include -#include "all_tsschecker.h" +#include "debug.h" int downloadFile(const char *url, const char *dstPath); diff --git a/tsschecker/main.c b/tsschecker/main.c index 1cc4b648..a56989f8 100644 --- a/tsschecker/main.c +++ b/tsschecker/main.c @@ -18,19 +18,20 @@ #include #include #include + #include "download.h" #include "tsschecker.h" -#include "all_tsschecker.h" +#include "all.h" +#include "debug.h" -#define FLAG_LIST_IOS 1 << 0 -#define FLAG_LIST_DEVICES 1 << 1 -#define FLAG_BUILDMANIFEST 1 << 2 -#define FLAG_LATEST_IOS 1 << 3 +#define FLAG_LIST_IOS (1 << 0) +#define FLAG_LIST_DEVICES (1 << 1) +#define FLAG_BUILDMANIFEST (1 << 2) +#define FLAG_LATEST_IOS (1 << 3) int idevicerestore_debug; #define reterror(code,a ...) {error(a); err = code; goto error;} - static struct option longopts[] = { { "build-manifest", required_argument, NULL, 'm' }, { "device", required_argument, NULL, 'd' }, @@ -44,55 +45,53 @@ static struct option longopts[] = { { "update-install", optional_argument, NULL, 'u' }, { "boardconfig", required_argument, NULL, 'B' }, { "buildid", required_argument, NULL, 'Z' }, - { "debug", no_argument, NULL, 0 }, - { "list-devices", no_argument, NULL, 1 }, - { "list-ios", no_argument, NULL, 2 }, - { "save-path", required_argument, NULL, 3 }, - { "print-tss-request", no_argument, NULL, 4 }, - { "print-tss-response", no_argument, NULL, 5 }, - { "beta", no_argument, NULL, 6 }, - { "nocache", no_argument, NULL, 7 }, - { "apnonce", required_argument, NULL, 8 }, - { "sepnonce", required_argument, NULL, 9 }, - { "raw", required_argument, NULL, 10 }, + { "debug", no_argument, NULL, 0 }, + { "list-devices", no_argument, NULL, 1 }, + { "list-ios", no_argument, NULL, 2 }, + { "save-path", required_argument, NULL, 3 }, + { "print-tss-request", no_argument, NULL, 4 }, + { "print-tss-response", no_argument, NULL, 5 }, + { "beta", no_argument, NULL, 6 }, + { "nocache", no_argument, NULL, 7 }, + { "apnonce", required_argument, NULL, 8 }, + { "sepnonce", required_argument, NULL, 9 }, + { "raw", required_argument, NULL, 10 }, { "generator", required_argument, NULL, 'g' }, - { "bbsnum", required_argument, NULL, 11 }, + { "bbsnum", required_argument, NULL, 11 }, { NULL, 0, NULL, 0 } }; void cmd_help(){ printf("Usage: tsschecker [OPTIONS]\n"); - printf("Checks (real) signing status of device/firmware\n\n"); - - printf(" -d, --device MODEL\t\tspecific device by its MODEL (eg. iPhone4,1)\n"); - printf(" -i, --ios VERSION\t\tspecific iOS version (eg. 6.1.3)\n"); - printf(" --buildid BUILDID\t\tspecific buildid instead of iOS version (eg. 13C75)\n"); - printf(" -B, --boardconfig BOARD\tspecific boardconfig instead of iPhone model (eg. n61ap)\n"); + printf("Works with signing technology on iOS devices\n\n"); + printf(" -d, --device MODEL\t\tspecific device by its MODEL (eg. iPhone11,8)\n"); + printf(" -i, --ios VERSION\t\tspecific iOS/tvOS/watchOS version (eg. 12.3.1)\n"); + printf(" --buildid BUILDID\t\tspecific build ID instead of iOS/tvOS/watchOS version (eg. 16F203)\n"); + printf(" -B, --boardconfig BOARD\tspecific boardconfig instead of device model (eg. n841ap)\n"); printf(" -h, --help\t\t\tprints usage information\n"); printf(" -o, --ota\t\t\tcheck OTA signing status, instead of normal restore\n"); printf(" -b, --no-baseband\t\tdon't check baseband signing status. Request a ticket without baseband\n"); - printf(" -m, --build-manifest\t\tmanually specify buildmanifest. (can be used with -d)\n"); - printf(" -s, --save\t\t\tsave fetched shsh blobs (mostly makes sense with -e)\n"); - printf(" -u, --update-install\t\t\trequest update ticket instead of erase\n"); + printf(" -m, --build-manifest\t\tmanually specify BuildManifest (can be used with -d)\n"); + printf(" -s, --save\t\t\tsave fetched signing tickets (mostly makes sense with -e)\n"); + printf(" -u, --update-install\t\trequest update ticket instead of erase\n"); printf(" -l, --latest\t\t\tuse latest public iOS version instead of manually specifying one\n"); - printf(" \t\tespecially useful with -s and -e for saving blobs\n"); - printf(" -e, --ecid ECID\t\tmanually specify ECID to be used for fetching blobs, instead of using random ones\n"); + printf(" \t\tespecially useful with -s and -e for saving tickets\n"); + printf(" -e, --ecid ECID\t\tmanually specify ECID to be used for fetching tickets, instead of using random ones\n"); printf(" \t\tECID must be either dec or hex eg. 5482657301265 or ab46efcbf71\n"); - printf(" --apnonce NONCE\t\tmanually specify APNONCE instead of using random one (not required for saving blobs)\n"); - printf(" --sepnonce NONCE\t\tmanually specify SEPNONCE instead of using random one (not required for saving blobs)\n"); + printf(" --apnonce NONCE\t\tmanually specify ApNonce instead of using random one (not required for saving tickets)\n"); + printf(" --sepnonce NONCE\t\tmanually specify SepNonce instead of using random one (not required for saving tickets)\n"); printf(" --bbsnum SNUM\t\tmanually specify BbSNUM, in hex, for saving valid BBTicket\n"); - printf(" --save-path PATH\t\tspecify path for saving blobs\n"); + printf(" --save-path PATH\t\tspecify path for saving tickets\n"); printf(" --generator GEN\t\tmanually specify generator in format 0x%%16llx\n"); - printf(" -h, --help\t\t\tprints usage information\n"); - printf(" --beta\t\t\trequest ticket for beta instead of normal relase (use with -o)\n"); + printf(" --beta\t\t\trequest signing tickets for 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 ios versions\n"); + printf(" --list-ios\t\tlist all known iOS versions\n"); printf(" --nocache \t\tignore caches and redownload required files\n"); printf(" --print-tss-request\n"); printf(" --print-tss-response\n"); - printf(" --raw\t\t\tsend raw file to Apple's tss server (useful for debugging)\n"); - printf("\n"); - printf("Homepage: <" PACKAGE_URL ">\n"); + printf(" --raw\t\t\tsend raw file to Apple's TSS server (useful for debugging)\n\n"); + printf("Homepage: https://github.com/s0uthwest/tsschecker\n"); + printf("Original project: https://github.com/tihmstar/tsschecker\n"); } int64_t parseECID(const char *ecid){ @@ -100,7 +99,7 @@ int64_t parseECID(const char *ecid){ int isHex = 0; int64_t ret = 0; - //in case hex ecid only contains digits, specify with 0x1235 + //in case hex ECID only contains digits, specify with 0x1235 if (strncmp(ecid, "0x", 2) == 0){ isHex = 1; ecidBK = ecid+2; @@ -151,7 +150,7 @@ char *parseNonce(const char *nonce, size_t *parsedLen){ int main(int argc, const char * argv[]) { int err = 0; int isSigned = 0; - printf("Version: "VERSION_COMMIT_SHA" - "VERSION_COMMIT_COUNT"\n"); + printf("Version: "TSSCHECKER_VERSION_SHA" - "TSSCHECKER_VERSION_COUNT"\n"); // versioning dbglog = 1; idevicerestore_debug = 0; @@ -198,7 +197,7 @@ int main(int argc, const char * argv[]) { case 'e': // long option: "ecid"; can be called as short option ecid = optarg; break; - case 'g': // long option: "ecid"; can be called as short option + case 'g': // long option: "generator"; can be called as short option if (optarg[0] != '0' && optarg[1] != 'x') goto failparse; devVals.generator[0] = '0'; @@ -275,7 +274,7 @@ int main(int argc, const char * argv[]) { rawFilePath = optarg; idevicerestore_debug = 1; break; - case 11: // --bbsnum + case 11: // only long option "bbsnum" bbsnum = optarg; break; default: @@ -289,7 +288,7 @@ int main(int argc, const char * argv[]) { size_t bufSize = 0; FILE *f = fopen(rawFilePath, "rb"); if (!f) - reterror(-100, "[TSSC] failed to read rawfile at \"%s\"\n",rawFilePath); + reterror(-100, "[TSSC] failed to read raw file at \"%s\"\n",rawFilePath); fseek(f, 0, SEEK_END); bufSize = ftell(f); fseek(f, 0, SEEK_SET); @@ -297,27 +296,25 @@ int main(int argc, const char * argv[]) { fread(buf, 1, bufSize, f); fclose(f); - printf("Sending TSS Request:\n%s",buf); + printf("Sending TSS request:\n%s",buf); char *rsp = tss_request_send_raw(buf, NULL, (int*)&bufSize); - printf("TSS Server Returned:\n%s\n",rsp); + printf("TSS server returned:\n%s\n",rsp); free(rsp); return 0; } - if (devVals.deviceBoard) for (int i=0; i=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"); else{ putchar('\n'); - reterror(-69, "[TSSC] checking tss status failed!\n"); + reterror(-69, "[TSSC] checking TSS status failed!\n"); } } - - error: if (devVals.deviceBoard) free(devVals.deviceBoard); if (devVals.deviceModel) free(devVals.deviceModel); diff --git a/tsschecker/tss.c b/tsschecker/tss.c index c0d4d640..9e1b25e5 100644 --- a/tsschecker/tss.c +++ b/tsschecker/tss.c @@ -103,7 +103,6 @@ char* ecid_to_string(uint64_t ecid) { } 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")); @@ -218,6 +217,7 @@ int tss_parameters_add_from_manifest(plist_t parameters, plist_t build_identity) } node = NULL; + /* BbCalibrationManifestKeyHash */ node = plist_dict_get_item(build_identity, "BbCalibrationManifestKeyHash"); if (node && plist_get_node_type(node) == PLIST_DATA) { plist_dict_set_item(parameters, "BbCalibrationManifestKeyHash", plist_copy(node)); @@ -297,6 +297,51 @@ int tss_parameters_add_from_manifest(plist_t parameters, plist_t build_identity) } } node = NULL; + + /* Yonkers,BoardID - Used for Yonkers firmware request */ + node = plist_dict_get_item(build_identity, "Yonkers,BoardID"); + if (node) { + if (plist_get_node_type(node) == PLIST_STRING) { + char *strval = NULL; + int intval = 0; + plist_get_string_val(node, &strval); + sscanf(strval, "%x", &intval); + plist_dict_set_item(parameters, "Yonkers,BoardID", plist_new_uint(intval)); + } else { + plist_dict_set_item(parameters, "Yonkers,BoardID", plist_copy(node)); + } + } + node = NULL; + + /* Yonkers,ChipID - Used for Yonkers firmware request */ + node = plist_dict_get_item(build_identity, "Yonkers,ChipID"); + if (node) { + if (plist_get_node_type(node) == PLIST_STRING) { + char *strval = NULL; + int intval = 0; + plist_get_string_val(node, &strval); + sscanf(strval, "%x", &intval); + plist_dict_set_item(parameters, "Yonkers,ChipID", plist_new_uint(intval)); + } else { + plist_dict_set_item(parameters, "Yonkers,ChipID", plist_copy(node)); + } + } + node = NULL; + + /* add Yonkers,PatchEpoch - Used for Yonkers firmware request */ + node = plist_dict_get_item(build_identity, "Yonkers,PatchEpoch"); + if (node) { + if (plist_get_node_type(node) == PLIST_STRING) { + char *strval = NULL; + int intval = 0; + plist_get_string_val(node, &strval); + sscanf(strval, "%x", &intval); + plist_dict_set_item(parameters, "Yonkers,PatchEpoch", plist_new_uint(intval)); + } else { + plist_dict_set_item(parameters, "Yonkers,PatchEpoch", plist_copy(node)); + } + } + node = NULL; /* add build identity manifest dictionary */ node = plist_dict_get_item(build_identity, "Manifest"); @@ -325,7 +370,7 @@ int tss_request_add_ap_img4_tags(plist_t request, plist_t parameters) { return -1; } plist_dict_set_item(request, "ApNonce", plist_copy(node)); - }else + } else plist_dict_set_item(request, "ApNonce", plist_new_data(NULL, 0)); node = NULL; @@ -581,7 +626,7 @@ int tss_request_add_ap_tags(plist_t request, plist_t parameters, plist_t overrid continue; } - /* FIXME: only used with diagnostics firmware */ + /* only used with diagnostics firmware */ if ((strcmp(key, "Diags") == 0)) { free(key); continue; @@ -650,6 +695,7 @@ int tss_request_add_baseband_tags(plist_t request, plist_t parameters, plist_t o } node = NULL; + /* BbCalibrationManifestKeyHash */ node = plist_dict_get_item(parameters, "BbCalibrationManifestKeyHash"); if (node) { plist_dict_set_item(request, "BbCalibrationManifestKeyHash", plist_copy(node)); @@ -770,6 +816,15 @@ int tss_request_add_se_tags(plist_t request, plist_t parameters, plist_t overrid } plist_dict_set_item(request, "SE,Nonce", plist_copy(node)); node = NULL; + + /* add SE,OSUPubKeyID */ + node = plist_dict_get_item(parameters, "SE,OSUPubKeyID"); + if (!node) { + tsserror("ERROR: %s: Unable to find required SE,OSUPubKeyID in parameters\n", __func__); + return -1; + } + plist_dict_set_item(request, "SE,OSUPubKeyID", plist_copy(node)); + node = NULL; /* add SE,RootKeyIdentifier */ node = plist_dict_get_item(parameters, "SE,RootKeyIdentifier"); @@ -781,12 +836,10 @@ int tss_request_add_se_tags(plist_t request, plist_t parameters, plist_t overrid node = NULL; /* 'IsDev' determines whether we have Production or Development */ - const char *removing_cmac_key = "DevelopmentCMAC"; - node = plist_dict_get_item(parameters, "SE,IsDev"); - if (node && plist_get_node_type(node) == PLIST_BOOLEAN) { - uint8_t is_dev = 0; - plist_get_bool_val(node, &is_dev); - removing_cmac_key = (is_dev) ? "ProductionCMAC" : "DevelopmentCMAC"; + uint8_t is_dev = 0; + plist_get_bool_val(node, &is_dev); + if (node && plist_get_node_type(node) == PLIST_BOOLEAN) { + plist_get_bool_val(node, &is_dev); } /* add SE,* components from build manifest to request */ @@ -817,8 +870,16 @@ int tss_request_add_se_tags(plist_t request, plist_t parameters, plist_t overrid plist_dict_remove_item(tss_entry, "Info"); /* remove 'DevelopmentCMAC' (or 'ProductionCMAC') node */ - if (plist_dict_get_item(tss_entry, removing_cmac_key)) { - plist_dict_remove_item(tss_entry, removing_cmac_key); + if (is_dev) { + if (plist_dict_get_item(tss_entry, "ProductionCMAC")) + plist_dict_remove_item(tss_entry, "ProductionCMAC"); + if (plist_dict_get_item(tss_entry, "ProductionUpdatePayloadHash")) + plist_dict_remove_item(tss_entry, "ProductionUpdatePayloadHash"); + } else { + if (plist_dict_get_item(tss_entry, "DevelopmentCMAC")) + plist_dict_remove_item(tss_entry, "DevelopmentCMAC"); + if (plist_dict_get_item(tss_entry, "DevelopmentUpdatePayloadHash")) + plist_dict_remove_item(tss_entry, "DevelopmentUpdatePayloadHash"); } /* add entry to request */ @@ -836,7 +897,7 @@ int tss_request_add_se_tags(plist_t request, plist_t parameters, plist_t overrid return 0; } -int tss_request_add_savage_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) { plist_t node = NULL; @@ -916,23 +977,39 @@ int tss_request_add_savage_tags(plist_t request, plist_t parameters, plist_t ove uint8_t isprod = 0; plist_get_bool_val(node, &isprod); node = NULL; + + /* get the right Savage component name */ + comp_name = (isprod) ? "Savage,B0-Prod-Patch" : "Savage,B0-Dev-Patch"; + node = plist_dict_get_item(parameters, "Savage,Revision"); + if (node && (plist_get_node_type(node) == PLIST_DATA)) { + unsigned char *savage_rev = NULL; + uint64_t savage_rev_len = 0; + plist_get_data_val(node, (char**)&savage_rev, &savage_rev_len); + if (savage_rev_len > 0) { + if (((savage_rev[0] | 0x10) & 0xF0) == 0x30) { + comp_name = (isprod) ? "Savage,B2-Prod-Patch" : "Savage,B2-Dev-Patch"; + } else if ((savage_rev[0] & 0xF0) == 0xA0) { + comp_name = (isprod) ? "Savage,BA-Prod-Patch" : "Savage,BA-Dev-Patch"; + } + } + free(savage_rev); + } + + /* add Savage,B?-*-Patch */ + node = plist_dict_get_item(manifest_node, comp_name); + if (!node) { + tsserror("ERROR: Unable to get %s entry from manifest\n", comp_name); + return -1; + } + dict = plist_copy(node); + plist_dict_remove_item(dict, "Info");; + plist_dict_set_item(request, comp_name, dict); - /* add Savage,B2-*-Patch */ - if (isprod) { - comp_name = "Savage,B2-Prod-Patch"; - } else { - comp_name = "Savage,B2-Dev-Patch"; - } - node = plist_access_path(manifest_node, 2, comp_name, "Digest"); - if (!node) { - tsserror("ERROR: Unable to get %s digest from manifest\n", comp_name); - return -1; - } - dict = plist_new_dict(); - plist_dict_set_item(dict, "Digest", plist_copy(node)); - plist_dict_set_item(request, comp_name, dict); - - /* add Savage,Nonce */ + if (component_name) { + *component_name = strdup(comp_name); + } + + /* add Savage,Nonce */ node = plist_dict_get_item(parameters, "Savage,Nonce"); if (!node) { tsserror("ERROR: Unable to find required Savage,Nonce in parameters\n"); @@ -958,6 +1035,116 @@ int tss_request_add_savage_tags(plist_t request, plist_t parameters, plist_t ove return 0; } +int tss_request_add_yonkers_tags(plist_t request, plist_t parameters, plist_t overrides, char **component_name) +{ + 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) { + error("ERROR: %s: Unable to get restore manifest from parameters\n", __func__); + return -1; + } + + /* add tags indicating we want to get the Savage,Ticket */ + plist_dict_set_item(request, "@BBTicket", plist_new_bool(1)); + plist_dict_set_item(request, "@Yonkers,Ticket", plist_new_bool(1)); + + /* add SEP */ + node = plist_access_path(manifest_node, 2, "SEP", "Digest"); + if (!node) { + error("ERROR: Unable to get SEP digest from manifest\n"); + return -1; + } + plist_t dict = plist_new_dict(); + plist_dict_set_item(dict, "Digest", plist_copy(node)); + plist_dict_set_item(request, "SEP", dict); + + { + static const char *keys[] = {"Yonkers,AllowOfflineBoot", "Yonkers,BoardID", "Yonkers,ChipID", "Yonkers,ECID", "Yonkers,Nonce", "Yonkers,PatchEpoch", "Yonkers,ProductionMode", "Yonkers,ReadECKey", "Yonkers,ReadFWKey", }; + int i; + 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]); + } + plist_dict_set_item(request, keys[i], plist_copy(node)); + node = NULL; + } + } + + char *comp_name = NULL; + plist_t comp_node = NULL; + uint8_t isprod = 1; + uint64_t fabrevision = (uint64_t)-1; + + node = plist_dict_get_item(parameters, "Yonkers,ProductionMode"); + if (node && (plist_get_node_type(node) == PLIST_BOOLEAN)) { + plist_get_bool_val(node, &isprod); + } + + node = plist_dict_get_item(parameters, "Yonkers,FabRevision"); + if (node && (plist_get_node_type(node) == PLIST_UINT)) { + plist_get_uint_val(node, &fabrevision); + } + + 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, "Yonkers,", 8) == 0) { + int target_node = 1; + plist_t sub_node; + if ((sub_node = plist_dict_get_item(node, "EPRO")) != NULL && plist_get_node_type(sub_node) == PLIST_BOOLEAN) { + uint8_t b = 0; + plist_get_bool_val(sub_node, &b); + target_node &= ((isprod) ? b : !b); + } + if ((sub_node = plist_dict_get_item(node, "FabRevision")) != NULL && plist_get_node_type(sub_node) == PLIST_UINT) { + uint64_t v = 0; + plist_get_uint_val(sub_node, &v); + target_node &= (v == fabrevision); + } + if (target_node) { + comp_node = node; + break; + } + } + free(comp_name); + } + free(iter); + + if (comp_name == NULL) { + error("ERROR: No Yonkers node for %s/%lu\n", (isprod) ? "Production" : "Development", (unsigned long)fabrevision); + return -1; + } + + /* add Yonkers,SysTopPatch* */ + if (comp_node != NULL) { + plist_t comp_dict = plist_copy(comp_node); + plist_dict_remove_item(comp_dict, "Info"); + plist_dict_set_item(request, comp_name, comp_dict); + } + + if (component_name) { + *component_name = comp_name; + } else { + free(comp_name); + } + + /* 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) { @@ -979,12 +1166,12 @@ char* tss_request_send_raw(char* request, const char* server_url_string, int* re if (response_lenth) *response_lenth = 0; const char* urls[6] = { - "https://gs.apple.com/TSS/controller?action=2", - "https://17.111.103.65/TSS/controller?action=2", - "https://17.111.103.15/TSS/controller?action=2", - "http://gs.apple.com/TSS/controller?action=2", - "http://17.111.103.65/TSS/controller?action=2", - "http://17.111.103.15/TSS/controller?action=2" + "https://gs.apple.com/TSS/controller?action=2", // original TSS server's address + "https://17.171.36.30/TSS/controller?action=2", + "https://17.151.36.30/TSS/controller?action=2", + "http://gs.apple.com/TSS/controller?action=2", // original TSS server's address + "http://17.171.36.30/TSS/controller?action=2", + "http://17.151.36.30/TSS/controller?action=2" }; tss_response* response = NULL; @@ -1039,8 +1226,7 @@ char* tss_request_send_raw(char* request, const char* server_url_string, int* re status_code = 0; info("success\n"); break; - } - else { + } else { info("failure\n"); } @@ -1074,6 +1260,9 @@ char* tss_request_send_raw(char* request, const char* server_url_string, int* re } else if (status_code == 126) { // An internal error occured, most likely the request was malformed break; + } else if (status_code == 128) { + // Error that occurs when saving blobs on certain A8(X) devices + break; } else { error("ERROR: tss_send_request: Unhandled status code %d\n", status_code); } @@ -1134,7 +1323,6 @@ plist_t tss_request_send(plist_t tss_request, const char* server_url_string) { } static int tss_response_get_data_by_key(plist_t response, const char* name, unsigned char** buffer, unsigned int* length) { - plist_t node = plist_dict_get_item(response, name); if (!node || plist_get_node_type(node) != PLIST_DATA) { debug("DEBUG: %s: No entry '%s' in TSS response\n", __func__, name); diff --git a/tsschecker/tss.h b/tsschecker/tss.h index a422e7e7..882d966f 100644 --- a/tsschecker/tss.h +++ b/tsschecker/tss.h @@ -21,18 +21,17 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef IDEVICERESTORE_TSS_H -#define IDEVICERESTORE_TSS_H +#ifndef TSS_H +#define TSS_H #ifdef __cplusplus extern "C" { #endif #include -#include "all_tsschecker.h" +#include "debug.h" extern int print_tss_request; - /* parameters */ int tss_parameters_add_from_manifest(plist_t parameters, plist_t build_identity); @@ -45,7 +44,8 @@ int tss_request_add_common_tags(plist_t request, plist_t parameters, plist_t ove int tss_request_add_ap_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); +int tss_request_add_savage_tags(plist_t request, plist_t parameters, plist_t overrides, char **component_name); +int tss_request_add_yonkers_tags(plist_t request, plist_t parameters, plist_t overrides, char **component_name); int tss_request_add_ap_img4_tags(plist_t request, plist_t parameters); int tss_request_add_ap_img3_tags(plist_t request, plist_t parameters); @@ -69,4 +69,4 @@ char* ecid_to_string(uint64_t ecid); } #endif -#endif +#endif /* tss_h */ diff --git a/tsschecker/tsschecker.c b/tsschecker/tsschecker.c index 1312ef4b..0d3838d4 100644 --- a/tsschecker/tsschecker.c +++ b/tsschecker/tsschecker.c @@ -1,5 +1,5 @@ // -// ipswme.c +// tsschecker.c // tsschecker // // Created by tihmstar on 07.01.16. @@ -19,10 +19,12 @@ #include #include #include -#include "tsschecker.h" -#include "download.h" + #include #include + +#include "tsschecker.h" +#include "download.h" #include "tss.h" #ifdef __APPLE__ @@ -36,10 +38,10 @@ #define FIRMWARE_JSON_URL "https://api.ipsw.me/v2.1/firmwares.json/condensed" #define FIRMWARE_OTA_JSON_URL "https://api.ipsw.me/v2.1/ota.json/condensed" -#define NONCELEN_BASEBAND 20 -#define NONCELEN_SEP 20 +#define NONCELEN_BASEBAND 20 // for devices with KTRR - 32 +#define NONCELEN_SEP 20 // for devices with KTRR - 32 -#define swapchar(a,b) ((a) ^= (b),(b) ^= (a),(a) ^= (b)) //swaps a and b, unless they are the same variable +#define swapchar(a,b) ((a) ^= (b),(b) ^= (a),(a) ^= (b)) //swaps a and b, unless they're the same variable #define printJString(str) printf("%.*s",(int)str->size,str->value) #ifdef WIN32 @@ -69,8 +71,8 @@ static const char *win_path_get(enum paths path){ size_t len = strlen(tmp) + strlen(win_pathvars[path]) + 1; win_paths[path] = (char *)malloc(len); memset((char*)win_paths[path], '\0', len); - strncat((char*)win_paths[path], tmp, strlen(tmp)); - strncat((char*)win_paths[path], win_pathvars[path], strlen(win_pathvars[path])); + strcat((char*)win_paths[path], tmp); + strcat((char*)win_paths[path], win_pathvars[path]); return win_paths[path]; } @@ -94,14 +96,12 @@ static const char *win_path_get(enum paths path){ #define DIRECTORY_DELIMITER_STR "/" #define DIRECTORY_DELIMITER_CHR '/' - #include #define __mkdir(path, mode) mkdir(path, mode) #endif -#pragma mark getJson functions - +/* getJson functions */ int dbglog = 0; int print_tss_request = 0; int print_tss_response = 0; @@ -109,77 +109,132 @@ int nocache = 0; int save_shshblobs = 0; const char *shshSavePath = "."DIRECTORY_DELIMITER_STR; - +// iPhone & iPod touch (1st generations) doesn't have signing technology. static struct bbdevice bbdevices[] = { - {"iPod1,1", 0, 0}, - {"iPod2,1", 0, 0}, - {"iPod3,1", 0, 0}, - {"iPod4,1", 0, 0}, - {"iPod5,1", 0, 0}, - {"iPod7,1", 0, 0}, - - {"iPhone2,1", 0, 0}, - {"iPhone3,1", 257, 12}, - {"iPhone3,3", 2, 4}, - {"iPhone4,1", 2, 4}, - {"iPhone5,1", 3255536192, 4}, - {"iPhone5,2", 3255536192, 4}, - {"iPhone5,3", 3554301762, 4}, - {"iPhone5,4", 3554301762, 4}, - {"iPhone6,1", 3554301762, 4}, - {"iPhone6,2", 3554301762, 4}, - {"iPhone7,1", 3840149528, 4}, - {"iPhone7,2", 3840149528, 4}, - {"iPhone8,1", 3840149528, 4}, - {"iPhone8,2", 3840149528, 4}, - {"iPhone8,4", 3840149528, 4}, - {"iPhone9,1", 2315222105, 4}, - {"iPhone9,2", 2315222105, 4}, - {"iPhone9,3", 1421084145, 12}, - {"iPhone9,4", 1421084145, 12}, - {"iPhone10,1", 2315222105, 4}, - {"iPhone10,2", 2315222105, 4}, - {"iPhone10,3", 2315222105, 4}, - {"iPhone10,4", 524245983, 12}, - {"iPhone10,5", 524245983, 12}, - {"iPhone10,6", 524245983, 12}, - - {"iPad1,1", 0, 0}, - {"iPad2,1", 0, 0}, - {"iPad2,2", 257, 12}, - {"iPad2,4", 0, 0}, - {"iPad2,5", 0, 0}, - {"iPad3,1", 0, 0}, - {"iPad3,2", 4, 4}, - {"iPad3,3", 4, 4}, - {"iPad3,4", 0, 0}, - {"iPad3,6", 3255536192, 4}, - {"iPad4,1", 0, 0}, - {"iPad4,2", 3554301762, 4}, - {"iPad4,4", 0, 0}, - {"iPad4,5", 3554301762, 4}, - {"iPad4,7", 0, 0}, - {"iPad4,8", 3554301762, 4}, - {"iPad5,1", 0, 0}, - {"iPad5,2", 3840149528, 4}, - {"iPad5,3", 0, 0}, - {"iPad5,4", 3840149528, 4}, - {"iPad6,3", 0, 0}, - {"iPad6,4", 3840149528, 4}, - {"iPad6,7", 0, 0}, - {"iPad6,8", 3840149528, 4}, - {"iPad6,11", 0, 0}, - {"iPad6,12", 3840149528, 4}, - {"iPad7,1", 0, 0}, - {"iPad7,2", 2315222105, 4}, - {"iPad7,3", 0, 0}, - {"iPad7,4", 2315222105, 4}, - - {"AppleTV1,1", 0, 0}, - {"AppleTV2,1", 0, 0}, - {"AppleTV3,1", 0, 0}, - {"AppleTV3,2", 0, 0}, - {"AppleTV5,3", 0, 0}, + // iPod touches + {"iPod2,1", 0, 0}, // 2nd gen + {"iPod3,1", 0, 0}, // 3rd gen + {"iPod4,1", 0, 0}, // 4th gen + {"iPod5,1", 0, 0}, // 5th gen + {"iPod7,1", 0, 0}, // 6th gen + {"iPod9,1", 0, 0}, // 7th gen + + // iPhones + {"iPhone1,2", 0, 0}, // iPhone 3G + {"iPhone2,1", 0, 0}, // iPhone 3Gs + {"iPhone3,1", 257, 12}, // iPhone 4 GSM + {"iPhone3,2", 257, 12}, // iPhone 4 GSM (2012, Rev A) + {"iPhone3,3", 2, 4}, // iPhone 4 CDMA + {"iPhone4,1", 2, 4}, // iPhone 4s + {"iPhone5,1", 3255536192, 4}, // iPhone 5 (GSM) + {"iPhone5,2", 3255536192, 4}, // iPhone 5 (Global) + {"iPhone5,3", 3554301762, 4}, // iPhone 5c (GSM) + {"iPhone5,4", 3554301762, 4}, // iPhone 5c (Global) + {"iPhone6,1", 3554301762, 4}, // iPhone 5s (GSM) + {"iPhone6,2", 3554301762, 4}, // iPhone 5s (Global) + {"iPhone7,1", 3840149528, 4}, // iPhone 6 Plus + {"iPhone7,2", 3840149528, 4}, // iPhone 6 + {"iPhone8,1", 3840149528, 4}, // iPhone 6s + {"iPhone8,2", 3840149528, 4}, // iPhone 6s Plus + {"iPhone8,4", 3840149528, 4}, // iPhone SE + {"iPhone9,1", 2315222105, 4}, // iPhone 7 (Global) + {"iPhone9,2", 2315222105, 4}, // iPhone 7 Plus (Global) + {"iPhone9,3", 1421084145, 12}, // iPhone 7 GSM + {"iPhone9,4", 1421084145, 12}, // iPhone 7 Plus (GSM) + {"iPhone10,1", 2315222105, 4}, // iPhone 8 (Global) + {"iPhone10,2", 2315222105, 4}, // iPhone 8 Plus (Global) + {"iPhone10,3", 2315222105, 4}, // iPhone X (Global) + {"iPhone10,4", 524245983, 12}, // iPhone 8 (GSM) + {"iPhone10,5", 524245983, 12}, // iPhone 8 Plus (GSM) + {"iPhone10,6", 524245983, 12}, // iPhone X GSM + {"iPhone11,2", 165673526, 12}, // iPhone XS + {"iPhone11,4", 165673526, 12}, // iPhone XS Max (China) + {"iPhone11,6", 165673526, 12}, // iPhone XS Max (Global) + {"iPhone11,8", 165673526, 12}, // iPhone XR + // {"iPhone12,1", 524245983, 12}, // iPhone 11 + // {"iPhone12,3", 524245983, 12}, // iPhone 11 Pro + // {"iPhone12,5", 524245983, 12}, // iPhone 11 Pro Max + + // iPads + {"iPad1,1", 0, 0}, // iPad (1st gen) + {"iPad2,1", 0, 0}, // iPad 2 Wi-Fi + {"iPad2,2", 257, 12}, // iPad 2 GSM + {"iPad2,3", 257, 12}, // iPad 2 CDMA + {"iPad2,4", 0, 0}, // iPad 2 Wi-Fi (2012, Rev A) + {"iPad3,1", 0, 0}, // the new iPad (3rd gen, Wi-Fi) + {"iPad3,2", 4, 4}, // the new iPad (3rd gen, CDMA) + {"iPad3,3", 4, 4}, // the new iPad (3rd gen, GSM) + {"iPad3,4", 0, 0}, // iPad with Retina display (4th gen, Wi-Fi) + {"iPad3,5", 3255536192, 4}, // iPad with Retina display (4th gen, CDMA) + {"iPad3,6", 3255536192, 4}, // iPad with Retina display (4th gen, GSM) + {"iPad6,11", 0, 0}, // iPad (5th gen, 2017, Wi-Fi) + {"iPad6,12", 3840149528, 4}, // iPad (5th gen, 2017, Cellular) + {"iPad7,5", 0, 0}, // iPad (6th gen, 2018, Wi-Fi) + {"iPad7,6", 3840149528, 4}, // iPad (6th gen, 2018, Cellular) + {"iPad7,11", 0, 0}, // iPad (7th gen, 2019, Wi-Fi) + // {"iPad7,12", 524245983, 12}, // iPad (7th gen, 2019, Cellular) + + // iPad minis + {"iPad2,5", 0, 0}, // iPad mini (1st gen, Wi-Fi) + {"iPad2,6", 3255536192, 4}, // iPad mini (1st gen, CDMA) + {"iPad2,7", 3255536192, 4}, // iPad mini (1st gen, GSM) + {"iPad4,4", 0, 0}, // iPad mini 2 (Wi-Fi) + {"iPad4,5", 3554301762, 4}, // iPad mini 2 (Cellular) + {"iPad4,6", 3554301762, 4}, // iPad mini 2 (Cellular, China) + {"iPad4,7", 0, 0}, // iPad mini 3 (Wi-Fi) + {"iPad4,8", 3554301762, 4}, // iPad mini 3 (Cellular) + {"iPad4,9", 3554301762, 4}, // iPad mini 3 (Cellular, China) + {"iPad5,1", 0, 0}, // iPad mini 4 (Wi-Fi) + {"iPad5,2", 3840149528, 4}, // iPad mini 4 (Cellular) + {"iPad11,1", 0, 0}, // iPad mini (5th gen, Wi-Fi) + {"iPad11,2", 165673526, 12}, // iPad mini (5th gen, Cellular) + + // iPad Airs + {"iPad4,1", 0, 0}, // iPad Air (Wi-Fi) + {"iPad4,2", 3554301762, 4}, // iPad Air (Cellular) + {"iPad4,3", 3554301762, 4}, // iPad Air (Cellular, China) + {"iPad5,3", 0, 0}, // iPad Air 2 (Wi-Fi) + {"iPad5,4", 3840149528, 4}, // iPad Air 2 (Cellular) + {"iPad11,3", 0, 0}, // iPad Air (3rd gen, Wi-Fi) + {"iPad11,4", 165673526, 12}, // iPad Air (3rd gen, Cellular) + + // iPad Pros + {"iPad6,3", 0, 0}, // iPad Pro (9,7", Wi-Fi) + {"iPad6,4", 3840149528, 4}, // iPad Pro (9,7", Cellular) + {"iPad6,7", 0, 0}, // iPad Pro (12.9", 1st gen, Wi-Fi) + {"iPad6,8", 3840149528, 4}, // iPad Pro (12.9", 1st gen, Cellular) + {"iPad7,1", 0, 0}, // iPad Pro (12.9", 2nd gen, Wi-Fi) + {"iPad7,2", 2315222105, 4}, // iPad Pro (12.9", 1st gen, Cellular) + {"iPad7,3", 0, 0}, // iPad Pro (10,5", Wi-Fi) + {"iPad7,4", 2315222105, 4}, // iPad Pro (10,5", Cellular) + {"iPad8,1", 0, 0}, // iPad Pro (11", Wi-Fi) + {"iPad8,2", 0, 0}, // iPad Pro (11", 1 TB model, Wi-Fi) + {"iPad8,3", 165673526, 12}, // iPad Pro 11", Cellular) + {"iPad8,4", 165673526, 12}, // iPad Pro 11", 1 TB model, Cellular) + {"iPad8,5", 0, 0}, // iPad Pro (12,9", 3rd gen, Wi-Fi) + {"iPad8,6", 0, 0}, // iPad Pro (12,9", 3rd gen, 1 TB model, Wi-Fi) + {"iPad8,7", 165673526, 12}, // iPad Pro 12,9", 3rd gen, Cellular) + {"iPad8,8", 165673526, 12}, // iPad Pro 12,9", 3rd gen, 1 TB model, Cellular) + + // Apple Watches + {"Watch1,1", 0, 0}, // Series 0 (38 mm) + {"Watch1,2", 0, 0}, // Series 0 (42 mm) + {"Watch2,3", 0, 0}, // Series 2 (38 mm) + {"Watch2,4", 0, 0}, // Series 2 (42 mm) + {"Watch2,6", 0, 0}, // Series 1 (38 mm) + {"Watch2,7", 0, 0}, // Series 1 (42 mm) + {"Watch3,3", 0, 0}, // Series 3 (38 mm) + {"Watch3,4", 0, 0}, // Series 3 (42 mm) + {"Watch4,1", 0, 0}, // Series 4 (40 mm) + {"Watch4,2", 0, 0}, // Series 4 (44 mm) + + // Apple TVs + {"AppleTV1,1", 0, 0}, // 1st gen + {"AppleTV2,1", 0, 0}, // 2nd gen + {"AppleTV3,1", 0, 0}, // 3rd gen + {"AppleTV3,2", 0, 0}, // 3rd gen (2013) + {"AppleTV5,3", 0, 0}, // 4th gen + {"AppleTV6,2", 0, 0}, // 4K {NULL, 0, 0} }; @@ -219,13 +274,12 @@ char *getOtaJson(){ return fJson; } -#pragma mark more get functions - +/* more get functions */ const char *getBoardconfigFromModel(const char *model){ const char *rt = NULL; irecv_device_t table = irecv_devices_get_all(); - //iterate through table until find correct entry - //table is terminated with {NULL, NULL, -1, -1} entry, return that if device not found + /* iterate through table until find correct entry + table is terminated with {NULL, NULL, -1, -1} entry, return that if device not found */ while (table->product_type){ if (strcasecmp(model, table->product_type) == 0){ if (rt){ @@ -234,18 +288,16 @@ const char *getBoardconfigFromModel(const char *model){ }else rt = table->hardware_model; } - table++; } - return rt; } const char *getModelFromBoardconfig(const char *boardconfig){ const char *rt = NULL; irecv_device_t table = irecv_devices_get_all(); - //iterate through table until find correct entry - //table is terminated with {NULL, NULL, -1, -1} entry, return that if device not found + /* iterate through table until find correct entry + table is terminated with {NULL, NULL, -1, -1} entry, return that if device not found */ while (table->product_type){ if (strcasecmp(boardconfig, table->hardware_model) == 0){ if (rt){ @@ -254,10 +306,8 @@ const char *getModelFromBoardconfig(const char *boardconfig){ }else rt = table->product_type; } - table++; } - return rt; } @@ -284,11 +334,9 @@ plist_t getBuildidentityWithBoardconfig(plist_t buildManifest, const char *board } char *string = NULL; plist_get_string_val(RestoreBehavior, &string); - //assuming there are only Erase and Update. If it's not Erase it must be Update - //also converting isUpdateInstall to bool (1 or 0) + //assuming there are only Erase and Update. If it's not Erase it must be Update also converting isUpdateInstall to bool (1 or 0) if ((strncmp(string, "Erase", strlen(string)) != 0) == !isUpdateInstall){ - //continue when Erase found but isUpdateInstall is true - //or Update found and isUpdateInstall is false + //continue when Erase found but isUpdateInstall is true or Update found and isUpdateInstall is false rt = NULL; continue; } @@ -302,7 +350,6 @@ plist_t getBuildidentityWithBoardconfig(plist_t buildManifest, const char *board rt = NULL; else break; - } error: @@ -316,7 +363,7 @@ plist_t getBuildidentity(plist_t buildManifest, const char *model, int isUpdateI const char *boardconfig = getBoardconfigFromModel(model); if (!boardconfig) - reterror("[TSSR] cant find boardconfig for device=%s please manuall use --boardconfig\n",model); + reterror("[TSSR] can't find boardconfig for device=%s please use --boardconfig\n",model); rt = getBuildidentityWithBoardconfig(buildManifest, boardconfig, isUpdateInstall); @@ -325,11 +372,8 @@ plist_t getBuildidentity(plist_t buildManifest, const char *model, int isUpdateI #undef reterror } - -#pragma mark json functions - +/* json functions */ long parseTokens(const char *json, jssytok_t **tokens){ - log("[JSON] counting elements\n"); long tokensCnt = jssy_parse(json, strlen(json), NULL, 0); *tokens = (jssytok_t*)malloc(sizeof(jssytok_t) * tokensCnt); @@ -338,8 +382,7 @@ long parseTokens(const char *json, jssytok_t **tokens){ return jssy_parse(json, strlen(json), *tokens, sizeof(jssytok_t) * tokensCnt); } -#pragma mark get functions - +/* get functions (again) */ //returns NULL terminated array of t_versionURL objects t_versionURL *getFirmwareUrls(const char *deviceModel, t_iosVersion *versVals, jssytok_t *tokens){ t_versionURL *rets = NULL; @@ -357,7 +400,6 @@ t_versionURL *getFirmwareUrls(const char *deviceModel, t_iosVersion *versVals, j memset(rets = (t_versionURL*)malloc(sizeof(t_versionURL)*(retcounter+1)), 0, sizeof(t_versionURL)*(retcounter+1)); rets_base = rets; - jssytok_t *tmp = firmwares->subval; for (size_t i=0; isize; tmp=tmp->next, i++) { jssytok_t *ios = jssy_dictGetValueForKey(tmp, (versVals->buildID) ? "buildid" : "version"); @@ -381,18 +423,17 @@ t_versionURL *getFirmwareUrls(const char *deviceModel, t_iosVersion *versVals, j versVals->version[i_vers->size] = '\0'; } - if (!rets) retcounter++; else{ for (int i=0; rets_base[i].buildID; i++) { if (strncmp(rets_base[i].buildID, i_build->value, i_build->size) == 0){ - info("[TSSC] Marking duplicated buildid %s\n",rets_base[i].buildID); + info("[TSSC] Marking duplicated build ID %s\n",rets_base[i].buildID); rets->isDupulicate = 1; break; } } - info("[TSSC] got firmwareurl for iOS %.*s build %.*s\n",(int)i_vers->size, i_vers->value,(int)i_build->size, i_build->value); + info("[TSSC] got firmware URL for iOS %.*s build %.*s\n",(int)i_vers->size, i_vers->value,(int)i_build->size, i_build->value); rets->version = (char*)malloc(i_vers->size+1); memcpy(rets->version, i_vers->value, i_vers->size); rets->version[i_vers->size] = '\0'; @@ -409,11 +450,9 @@ t_versionURL *getFirmwareUrls(const char *deviceModel, t_iosVersion *versVals, j } } - if (!retcounter) return NULL; else if (!rets) goto malloc_rets; - return (t_versionURL*)rets_base; } @@ -432,7 +471,7 @@ int downloadPartialzip(const char *url, const char *file, const char *dst){ log("[LFZP] downloading %s from %s\n\n",file,url); fragmentzip_t *info = fragmentzip_open(url); if (!info) { - error("[LFZP] failed to open url\n"); + error("[LFZP] failed to open URL\n"); return -1; } int ret = fragmentzip_download_file(info, file, dst, fragmentzip_callback); @@ -452,17 +491,18 @@ char *getBuildManifest(char *url, const char *device, const char *version, const char *fileDir = malloc(len); memset(fileDir, 0, len); - strncat(fileDir, MANIFEST_SAVE_PATH, strlen(MANIFEST_SAVE_PATH)); - strncat(fileDir, DIRECTORY_DELIMITER_STR, 1); - strncat(fileDir, device, strlen(device)); - strncat(fileDir, "_", strlen("_")); - strncat(fileDir, version, strlen(version)); + strcat(fileDir, MANIFEST_SAVE_PATH); + strcat(fileDir, DIRECTORY_DELIMITER_STR); + strcat(fileDir, device); + strcat(fileDir, "_"); + strcat(fileDir, version); + if (buildID){ - strncat(fileDir, "_", strlen("_")); - strncat(fileDir, buildID, strlen(buildID)); + strcat(fileDir, "_"); + strcat(fileDir, buildID); } - if (isOta) strncat(fileDir, "ota", strlen("ota")); + if (isOta) strcat(fileDir, "ota"); memset(&st, 0, sizeof(st)); if (stat(MANIFEST_SAVE_PATH, &st) == -1) __mkdir(MANIFEST_SAVE_PATH, 0700); @@ -477,8 +517,8 @@ char *getBuildManifest(char *url, const char *device, const char *version, const if (!url) { if (!f || nocache) return NULL; info("[TSSC] using cached Buildmanifest for %s\n",name); - }else info("[TSSC] opening Buildmanifest for %s\n",name); - + }else + info("[TSSC] opening Buildmanifest for %s\n",name); if (!f || nocache){ //download if it isn't there @@ -498,13 +538,11 @@ char *getBuildManifest(char *url, const char *device, const char *version, const buildmanifest[fsize] = '\0'; fclose(f); - free(fileDir); return buildmanifest; } t_bbdevice getBBDeviceInfo(const char *deviceModel){ - t_bbdevice bbdevs = bbdevices_get_all(); while (bbdevs->deviceModel && strcasecmp(bbdevs->deviceModel, deviceModel) != 0) @@ -524,16 +562,14 @@ void getRandNum(char *dst, size_t size, int base){ } } -#pragma mark tss functions - +/* TSS functions */ int tss_populate_devicevals(plist_t tssreq, uint64_t ecid, char *nonce, size_t nonce_size, char *sep_nonce, size_t sep_nonce_size, int image4supported){ - - plist_dict_set_item(tssreq, "ApECID", plist_new_uint(ecid)); //0000000000000000 + plist_dict_set_item(tssreq, "ApECID", plist_new_uint(ecid)); if (nonce) { - plist_dict_set_item(tssreq, "ApNonce", plist_new_data(nonce, nonce_size));//aa aa aa aa bb cc dd ee ff 00 11 22 33 44 55 66 77 88 99 aa + plist_dict_set_item(tssreq, "ApNonce", plist_new_data(nonce, nonce_size)); } - if (sep_nonce) {//aa aa aa aa bb cc dd ee ff 00 11 22 33 44 55 66 77 88 99 aa + if (sep_nonce) { plist_dict_set_item(tssreq, "ApSepNonce", plist_new_data(sep_nonce, sep_nonce_size)); } @@ -563,14 +599,11 @@ int tss_populate_basebandvals(plist_t tssreq, plist_t tssparameters, int64_t BbG } int64_t BbChipID = 0; - getRandNum(bbnonce, NONCELEN_BASEBAND, 256); srand((unsigned int)time(NULL)); int n=0; for (int i=1; i<7; i++) BbChipID += (rand() % 10) * pow(10, ++n); - /* BasebandNonce not required */ -// plist_dict_set_item(parameters, "BbNonce", plist_new_data(bbnonce, NONCELEN_BASEBAND)); plist_dict_set_item(parameters, "BbGoldCertId", plist_new_uint(BbGoldCertId)); plist_dict_set_item(parameters, "BbSNUM", plist_new_data((char *)BbSNUM, bbsnumSize)); @@ -619,16 +652,31 @@ int parseHex(const char *nonce, size_t *parsedLen, char *ret, size_t *retSize){ } int tss_populate_random(plist_t tssreq, int is64bit, t_devicevals *devVals){ - size_t nonceLen = 20; //valid for all devices up to iPhone7 + size_t nonceLen = 32; // valid for devices with pre-KTRR if (!devVals->deviceModel) return error("[TSSR] internal error: devVals->deviceModel is missing\n"),-1; - // TODO how can we determine this better? - if (strncasecmp(devVals->deviceModel, "iPhone9,", strlen("iPhone9,")) == 0 || - strncasecmp(devVals->deviceModel, "iPhone10,", strlen("iPhone10,")) == 0 || - strncasecmp(devVals->deviceModel, "iPad7,", strlen("iPad7,")) == 0 || - strncasecmp(devVals->deviceModel, "AppleTV6,", strlen("AppleTV6,")) == 0) - nonceLen = 32; + if (strncasecmp(devVals->deviceModel, "AppleTV2,", strlen("AppleTV2,")) == 0 || + strncasecmp(devVals->deviceModel, "AppleTV3,", strlen("AppleTV3,")) == 0 || + strncasecmp(devVals->deviceModel, "AppleTV5,", strlen("AppleTV5,")) == 0 || + strncasecmp(devVals->deviceModel, "iPad1,", strlen("iPad1,")) == 0 || + strncasecmp(devVals->deviceModel, "iPad2,", strlen("iPad2,")) == 0 || + strncasecmp(devVals->deviceModel, "iPad3,", strlen("iPad3,")) == 0 || + strncasecmp(devVals->deviceModel, "iPad4,", strlen("iPad4,")) == 0 || + strncasecmp(devVals->deviceModel, "iPad5,", strlen("iPad5,")) == 0 || + strncasecmp(devVals->deviceModel, "iPad6,", strlen("iPad6,")) == 0 || + strncasecmp(devVals->deviceModel, "iPhone2,", strlen("iPhone2,")) == 0 || + strncasecmp(devVals->deviceModel, "iPhone3,", strlen("iPhone3,")) == 0 || + strncasecmp(devVals->deviceModel, "iPhone4,", strlen("iPhone4,")) == 0 || + strncasecmp(devVals->deviceModel, "iPhone5,", strlen("iPhone5,")) == 0 || + strncasecmp(devVals->deviceModel, "iPhone6,", strlen("iPhone6,")) == 0 || + strncasecmp(devVals->deviceModel, "iPhone7,", strlen("iPhone7,")) == 0 || + strncasecmp(devVals->deviceModel, "iPhone8,", strlen("iPhone8,")) == 0 || + strncasecmp(devVals->deviceModel, "iPod3,", strlen("iPod3,")) == 0 || + strncasecmp(devVals->deviceModel, "iPod4,", strlen("iPod4,")) == 0 || + strncasecmp(devVals->deviceModel, "iPod5,", strlen("iPod5,")) == 0 || + strncasecmp(devVals->deviceModel, "iPod7,", strlen("iPod7,")) == 0 ) + nonceLen = 20; // valid for devices without KTRR int n=0; srand((unsigned int)time(NULL)); @@ -638,12 +686,12 @@ int tss_populate_random(plist_t tssreq, int is64bit, t_devicevals *devVals){ if (!devVals->parsedApnonceLen) devVals->apnonce = NULL; else if (devVals->parsedApnonceLen != nonceLen) - return error("[TSSR] parsed APNoncelen != requiredAPNoncelen (%u != %u)\n",(unsigned int)devVals->parsedApnonceLen,(unsigned int)nonceLen),-1; + return error("[TSSR] parsed ApNoncelen != requiredApNoncelen (%u != %u)\n",(unsigned int)devVals->parsedApnonceLen,(unsigned int)nonceLen),-1; }else{ devVals->apnonce = (char*)malloc((devVals->parsedApnonceLen = nonceLen)+1); if (nonceLen == 20) { - //this is a pre iPhone7 device - //nonce is derived from generator with SHA1 + /* this is a pre-KTRR device + nonces is derived from generator with SHA1 */ unsigned char zz[9] = {0}; for (int i=0; igenerator)-1; i++) { @@ -662,7 +710,7 @@ int tss_populate_random(plist_t tssreq, int is64bit, t_devicevals *devVals){ makesha1: SHA1(zz, 8, (unsigned char*)devVals->apnonce); }else if (nonceLen == 32){ - unsigned char zz[8] = {0}; + unsigned char zz[9] = {0}; unsigned char genHash[48]; //SHA384 digest length for (int i=0; igenerator)-1; i++) { @@ -682,7 +730,7 @@ int tss_populate_random(plist_t tssreq, int is64bit, t_devicevals *devVals){ SHA384(zz, 8, genHash); memcpy(devVals->apnonce, genHash, 32); }else{ - return error("[TSSR] Automatic generator->nonce calculation failed. Unknown device with noncelen=%u\n",(unsigned int)nonceLen),-1; + return error("[TSSR] Automatic generator->ApNonce calculation failed. Unknown device with ApNoncelen=%u\n",(unsigned int)nonceLen),-1; } } @@ -697,16 +745,14 @@ int tss_populate_random(plist_t tssreq, int is64bit, t_devicevals *devVals){ if (devVals->apnonce) devVals->apnonce[nonceLen] = '\0'; devVals->sepnonce[NONCELEN_SEP] = '\0'; - debug("[TSSR] ecid=%llu\n",devVals->ecid); - debug("[TSSR] nonce=%s\n",devVals->apnonce); - debug("[TSSR] sepnonce=%s\n",devVals->sepnonce); + debug("[TSSR] ECID=%llu\n",devVals->ecid); + debug("[TSSR] ApNonce=%s\n",devVals->apnonce); + debug("[TSSR] SEPNonce=%s\n",devVals->sepnonce); int rt = tss_populate_devicevals(tssreq, devVals->ecid, devVals->apnonce, devVals->parsedApnonceLen, devVals->sepnonce, devVals->parsedSepnonceLen, is64bit); return rt; } - - int tssrequest(plist_t *tssreqret, char *buildManifest, t_devicevals *devVals, t_basebandMode basebandMode){ #define reterror(a...) {error(a); error = -1; goto error;} int error = 0; @@ -763,19 +809,17 @@ int tssrequest(plist_t *tssreqret, char *buildManifest, t_devicevals *devVals, t plist_dict_set_item(tssreq, "@ApImg4Ticket", plist_new_bool(0)); if (plist_dict_get_item(tssreq, "@APTicket")) plist_dict_set_item(tssreq, "@APTicket", plist_new_bool(0)); - //TODO don't use .shsh2 ending and don't save generator when saving only baseband - info("[TSSR] User specified to request only a Baseband ticket.\n"); + // TO-DO: don't use .shsh2 ending and don't save generator when saving only baseband + info("[TSSR] User specified to request only a baseband ticket.\n"); } if (basebandMode != kBasebandModeWithoutBaseband) { - //TODO: verify that this being int64_t instead of uint64_t doesn't actually break something - + // TO-DO: verify that this being int64_t instead of uint64_t doesn't actually break something t_bbdevice bbinfo = getBBDeviceInfo(devVals->deviceModel); int64_t BbGoldCertId = devVals->bbgcid ? devVals->bbgcid : bbinfo->bbgcid; size_t bbsnumSize = devVals->bbsnumSize ? devVals->bbsnumSize : bbinfo->bbsnumSize; if (BbGoldCertId != bbinfo->bbgcid || bbsnumSize != bbinfo->bbsnumSize) { - info("\n[TSSR] Found undocumented baseband. Please file an issue at " PACKAGE_BUGREPORT - " with the following information:\n\t%s {\"%s\", " PRIi64 ", " PRIu64 "}\n\n", + info("\n[TSSR] Found undocumented baseband\n\n", devVals->deviceBoard, devVals->deviceModel, BbGoldCertId, bbsnumSize); } @@ -790,10 +834,10 @@ int tssrequest(plist_t *tssreqret, char *buildManifest, t_devicevals *devVals, t reterror("[TSSR] Error: Failed to populate baseband values\n"); } }else{ - log("[TSSR] LOG: device %s doesn't need a Baseband ticket, continuing without requesting a Baseband ticket\n",devVals->deviceModel); + log("[TSSR] LOG: device %s doesn't need a baseband ticket, continuing without requesting a Baseband ticket\n",devVals->deviceModel); } }else{ - info("[TSSR] User specified not to request a Baseband ticket.\n"); + info("[TSSR] User specified not to request a baseband ticket.\n"); } *tssreqret = tssreq; @@ -814,16 +858,15 @@ int isManifestBufSignedForDevice(char *buildManifestBuffer, t_devicevals *devVal plist_t apticket3 = NULL; if (tssrequest(&tssreq, buildManifestBuffer, devVals, basebandMode)) - reterror("[TSSR] faild to build tssrequest\n"); + reterror("[TSSR] faild to build TSS request\n"); isSigned = ((apticket = tss_request_send(tssreq, NULL)) > 0); - if (print_tss_response) debug_plist(apticket); if (isSigned && save_shshblobs){ if (!devVals->installType){ plist_t tssreq2 = NULL; - info("also requesting APTicket for installType=Update\n"); + info("also requesting APTicket for update installing\n"); devVals->installType = kInstallTypeUpdate; if (tssrequest(&tssreq2, buildManifestBuffer, devVals, basebandMode)){ warning("[TSSR] faild to build tssrequest for alternative installType\n"); @@ -833,8 +876,7 @@ int isManifestBufSignedForDevice(char *buildManifestBuffer, t_devicevals *devVal } if (tssreq2) plist_free(tssreq2); devVals->installType = kInstallTypeDefault; - } - { + } { plist_t tssreq2 = NULL; char *apnonce = devVals->apnonce; size_t apnonceLen = devVals->parsedApnonceLen; @@ -864,7 +906,6 @@ int isManifestBufSignedForDevice(char *buildManifestBuffer, t_devicevals *devVal plist_get_uint_val(pecid, &devVals->ecid); char *cecid = ecid_to_string(devVals->ecid); - uint32_t size = 0; char* data = NULL; if (*devVals->generator) @@ -875,7 +916,6 @@ int isManifestBufSignedForDevice(char *buildManifestBuffer, t_devicevals *devVal plist_dict_set_item(apticket, "noNonce", apticket3); plist_to_xml(apticket, &data, &size); - char *apnonce = ""; size_t apnonceLen = 0; @@ -905,13 +945,12 @@ int isManifestBufSignedForDevice(char *buildManifestBuffer, t_devicevals *devVal snprintf(fname+prePathLen, fnamelen, DIRECTORY_DELIMITER_STR"%s_%s_%s-%s_%s.shsh%s",cecid,tmpDevicename,cpvers,cbuild, apnonce, (*devVals->generator || apticket2) ? "2" : ""); - FILE *shshfile = fopen(fname, "w"); - if (!shshfile) error("[Error] can't save shsh at %s\n",fname); + if (!shshfile) error("[Error] can't save signing tickets at %s\n",fname); else{ fwrite(data, strlen(data), 1, shshfile); fclose(shshfile); - info("Saved shsh blobs!\n"); + info("Saved signing tickets!\n"); } if (apnonceLen) free(apnonce); @@ -940,7 +979,7 @@ int isManifestSignedForDevice(const char *buildManifestPath, t_devicevals *devVa char *bufManifest = NULL; info("[TSSC] opening %s\n",buildManifestPath); - //filehandling + //file handling FILE *fmanifest = fopen(buildManifestPath, "r"); if (!fmanifest) reterror("[TSSC] ERROR: file %s not found!\n",buildManifestPath); fseek(fmanifest, 0, SEEK_END); @@ -989,7 +1028,10 @@ int isVersionSignedForDevice(jssytok_t *firmwareTokens, t_iosVersion *versVals, #define reterror(a ... ) {error(a); goto error;} int nocacheorig = nocache; if (versVals->version && atoi(versVals->version) <= 3) { - info("[TSSC] version to check \"%s\" seems to be iOS 3 or lower, which did not require SHSH or APTicket.\n\tSkipping checks and returning true.\n",versVals->version); + /* NOTE: Signing tickets technology available with iPhone OS 3.x only for iPhone 3Gs & iPod touch (3rd generation). Other devices have signing technology since iOS 4. + So, iPhone and iPod touch (1st generations) doesn't have signing technology for all firmwares; iPhone 3G and iPod touch (2nd generation) have it only for iOS 4+. */ + /* TO-DO: Checking device for rather device checking on iPhone OS 3.0 for goodly request signing tickets. */ + info("[TSSC] version to check \"%s\" seems to be iPhone OS 3 or lower, which did not require SHSH or APTicket.\n\tSkipping checks and returning true.\n",versVals->version); return 1; } @@ -998,13 +1040,13 @@ int isVersionSignedForDevice(jssytok_t *firmwareTokens, t_iosVersion *versVals, char *buildManifest = NULL; t_versionURL *urls = getFirmwareUrls(devVals->deviceModel, versVals, firmwareTokens); - if (!urls) reterror("[TSSC] ERROR: could not get url for device %s on iOS %s\n",devVals->deviceModel,(!versVals->version ? versVals->buildID : versVals->version)); + if (!urls) reterror("[TSSC] ERROR: could not get URL for device %s on iOS %s\n",devVals->deviceModel,(!versVals->version ? versVals->buildID : versVals->version)); int cursigned = 0; for (t_versionURL *u = urls; u->url; u++) { buildManifest = getBuildManifest(u->url, devVals->deviceModel, versVals->version, u->buildID, versVals->isOta); if (!buildManifest) { - error("[TSSC] ERROR: could not get BuildManifest for firmwareurl %s\n",u->url); + error("[TSSC] ERROR: could not get BuildManifest for firmware URL %s\n",u->url); continue; } @@ -1027,8 +1069,6 @@ int isVersionSignedForDevice(jssytok_t *firmwareTokens, t_iosVersion *versVals, } free(urls),urls = NULL; - - error: nocache = nocacheorig; if (buildManifest) free(buildManifest); @@ -1036,8 +1076,7 @@ int isVersionSignedForDevice(jssytok_t *firmwareTokens, t_iosVersion *versVals, #undef reterror } -#pragma mark print functions - +/* print functions */ char *getFirmwareUrl(const char *deviceModel, t_iosVersion *versVals, jssytok_t *tokens){ warning("FUNCTION IS DEPRECATED, USE getFirmwareUrls INSTEAD!\n"); t_versionURL *versions, *v; @@ -1059,7 +1098,7 @@ char *getFirmwareUrl(const char *deviceModel, t_iosVersion *versVals, jssytok_t return ret; } -#warning "print devices function doesn't actually check if devices are sorted. it assues they are sorted in json" +/* Print devices function doesn't actually check if devices are sorted. it assues they are sorted in json */ int printListOfDevices(jssytok_t *tokens){ #define MAX_PER_LINE 10 log("[JSON] printing device list\n"); @@ -1154,10 +1193,8 @@ char **getListOfiOSForDevice(jssytok_t *tokens, const char *device, int isOTA, i return versions; } - int printListOfiOSForDevice(jssytok_t *tokens, char *device, int isOTA){ #define MAX_PER_LINE 10 - int versionsCnt; char **versions = getListOfiOSForDevice(tokens, device, isOTA, &versionsCnt); @@ -1171,7 +1208,6 @@ int printListOfiOSForDevice(jssytok_t *tokens, char *device, int isOTA){ if (res == 0) continue; } - nextVer = atoi(versions[i]); if (currVer && currVer != nextVer) printf("\n"), rspn = 0; currVer = nextVer; @@ -1189,9 +1225,7 @@ int printListOfiOSForDevice(jssytok_t *tokens, char *device, int isOTA){ #undef MAX_PER_LINE } - -#pragma mark check functions - +/* check functions */ jssytok_t *getFirmwaresForDevice(const char *device, jssytok_t *tokens, int isOta){ jssytok_t *ctok = (isOta) ? tokens : jssy_dictGetValueForKey(tokens, "devices"); @@ -1204,7 +1238,6 @@ jssytok_t *getFirmwaresForDevice(const char *device, jssytok_t *tokens, int isOt } int checkFirmwareForDeviceExists(t_devicevals *devVals, t_iosVersion *versVals, jssytok_t *tokens){ - jssytok_t *firmwares = getFirmwaresForDevice(devVals->deviceModel, tokens, versVals->isOta); if (!firmwares) return 0; diff --git a/tsschecker/tsschecker.h b/tsschecker/tsschecker.h index c39a639a..0112ca12 100644 --- a/tsschecker/tsschecker.h +++ b/tsschecker/tsschecker.h @@ -1,13 +1,13 @@ // -// ipswme.h +// tsschecker.h // tsschecker // // Created by tihmstar on 07.01.16. // Copyright © 2016 tihmstar. All rights reserved. // -#ifndef tsscheker_h -#define tsscheker_h +#ifndef tsschecker_h +#define tsschecker_h #ifdef __cplusplus extern "C" { @@ -17,7 +17,7 @@ extern "C" { #include "jssy.h" #include #include "tss.h" -#include "all_tsschecker.h" +#include "debug.h" extern int dbglog; extern int print_tss_response; @@ -100,10 +100,8 @@ int isManifestSignedForDevice(const char *buildManifestPath, t_devicevals *devVa int isManifestBufSignedForDevice(char *buildManifestBuffer, t_devicevals *devVals, t_basebandMode basebandMode); int isVersionSignedForDevice(jssytok_t *firmwareTokens, t_iosVersion *versVals, t_devicevals *devVals); - jssytok_t *getFirmwaresForDevice(const char *device, jssytok_t *tokens, int isOta); - int checkFirmwareForDeviceExists(t_devicevals *devVals, t_iosVersion *versVals, jssytok_t *tokens); int downloadPartialzip(const char *url, const char *file, const char *dst); @@ -113,10 +111,8 @@ const char *getModelFromBoardconfig(const char *boardconfig); plist_t getBuildidentity(plist_t buildManifest, const char *model, int isUpdateInstall); plist_t getBuildidentityWithBoardconfig(plist_t buildManifest, const char *boardconfig, int isUpdateInstall); - - #ifdef __cplusplus } #endif -#endif /* tsscheker_h */ +#endif /* tsschecker_h */