Open-source project
tihmstar/tsschecker avatar
tihmstar/tsschecker

tsschecker: checking whether Apple will sign a firmware

a powerfull tool to check tss signing status of various devices and firmwares

765 stars173 forksC++LGPL-3.0

At a glance

What is it?
tsschecker is a C++ tool that queries Apple's TSS signing servers to find out whether a given firmware build is signed for a given device, and it can also list every device and every firmware Apple publishes. The README also explains the nonce rules that govern whether a saved signing ticket is reusable, and why the collision methods that worked on older devices are not reliable on newer ones.
Who is it for?
tsschecker fits a device researcher who needs to answer a concrete question about Apple's signing servers, such as which builds are signed for which hardware, or who wants to explore how the TSS server responds across combinations of device and version.
Can I use it commercially?
Yes, with conditions. LGPL-3.0 is a weak copyleft licence: you can use it inside commercial and closed-source software, but if you distribute changes to its own files, you must publish those changes under the same licence.
Is it still maintained?
Yes. The repository last received commits 27 days ago.
What is it written in?
Mainly C++, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

A question, asked of Apple's signing servers

tsschecker is described as a powerful tool to check the TSS signing status of various devices and firmware, and the README extends that to the specific platforms: various devices, and iOS, iPadOS, tvOS, and watchOS versions.

TSS is the server Apple uses to sign firmware for a particular device, and the interesting property of it is that the answer is not simply yes or no. A build can be signed for one device and not for another, and the set of signed combinations changes over time as Apple issues new builds. tsschecker exists to ask that question directly, and to record the answer.

The tool is explicitly not only for that. The README says it is also meant to explore Apple's TSS servers, and then gives the reason in the form of an observation you can act on: by using all of its customisation options, you might discover a combination of device and iOS version that is now getting signed but was not getting signed before.

That framing matters for how you read the rest of the documentation. tsschecker is as much an analysis tool for Apple's signing infrastructure as it is a checking tool, and the nonce and collision sections are the parts where that analysis is most specific.

The project is written in C++, licensed under LGPL-3.0, and not archived, with the last push on 2026-09-26. The release tags are build numbers rather than semantic versions, with 343 from 2024-08-06, 341 from 2024-08-01, and 304 from 2019-12-25, and the tag names carry the commit they were built from.

Lists, and the build manifest that names the firmware

The feature list is short and has three parts.

The first is enumeration. You can get lists of all devices, and all firmwares and over the air versions for a specific device, which is the discovery step, since you need to know the build identifier before you can ask about it.

The second is the check itself, which works by specifying a BuildManifest.plist. That file is the metadata that describes a firmware build, and pointing the tool at one is how you ask the question about a specific build without having to reconstruct the request by hand.

The third is the mode that does not need device specific values at all. The README says it works without specifying any device relevant values to check the signing status, and that in that mode it can be used to save blobs when given an ECID and the option for printing the TSS response, with the parenthesis that there are better tools to do that.

That parenthesis is a candid admission, and it is worth taking at face value. The device independent mode is the exploratory one, and the saving of blobs is a side effect of the request the tool makes rather than its purpose, and the author of the tool points you elsewhere for that job.

The ECID is the hardware identifier that the signing request is bound to, and passing one is how the tool simulates the request for a specific unit. That binding is also the root of the nonce discussion that follows, because a signing ticket is tied to the device that produced it.

Nonces, entangling, and why a ticket stops working

The nonce section is the most technical part of the README, and it is where the constraints of the system become visible.

The section on nonces gives recommended generators for saving tickets, and two values are listed with the context they are used in. One is the value used on the Electra and Chimera jailbreaks, and the other is the value used on the unc0ver jailbreak. Those are the nonce generators of specific jailbreak tools, and the recommended values are the ones that produce a nonce the signing server will accept for those devices.

Then there is nonce entangling, which the README explains for Apple A12 and newer devices, with the iPhone XR and the Apple Watch Series 4 given as examples. On those devices the nonce generated by the device is also derived from the UID, and is consequently device specific. The consequence is spelled out: to save a usable ticket for a newer device you need the nonce that your device actually generates, from your generator.

That is the crux. A ticket is a signed artefact bound to a nonce, and a nonce that is merely device specific rather than entropy derived produces a ticket that is usable on the device that generated it and nowhere else. The link to a discussion on the jailbreak forum is offered for how to obtain the actual boot nonce of a device.

The section on nonce collisions is where the README gets cautionary. The collision method only works on a few firmwares and devices and is not reliable, and the recommendation is to save a ticket with a generator and to use the checkm8 bootrom exploit instead.

The recovery collisions are said to occur only on a few iOS versions, with the iPhone 5s on iOS 9.3.3 and on iOS 10.1 to 10.2 given as the examples, and the reason given is that once you update, the nonces either generate differently or do not collide any more.

The device firmware update collisions are the opposite case, said to occur commonly on any device using the A7 and A8 chipsets regardless of the iOS version, and described as much more reliable than the recovery collisions.

Dependencies, and a build that is not a single command

The dependency section lists the external libraries that have to be installed on your system, and they are the usual set for a tool that talks to an Apple service and parses its responses.

There is libcurl for the HTTP requests, libfragmentzip for the compressed firmware archives, libirecovery for the device communication layer, libplist for property list parsing, and either OpenSSL or the CommonCrypto library on macOS and OS X. There is also a submodule, jssy, which has to compile on your system along with the rest.

An autotools build, a pkg-config file, and an Xcode project

The build itself is autotools. The repository has a Makefile.am, a configure.ac, and an autogen.sh script, which is the conventional three pieces for a project that has to build on more than one Unix-like system. There is also a libtsschecker.pc.in file, which is the template for a pkg-config file, so that other projects can find the library and its flags without hardcoded paths, and there is an Xcode project, which is how you build it on macOS.

The source is laid out in the usual way for that structure, with the implementation in a tsschecker directory, public headers in an include directory, and the external dependencies in an external directory alongside the submodule configuration.

The dependency set is the practical obstacle here, and it is worth being honest about the order of work. libcurl is easy, libplist is easy, libfragmentzip and libirecovery are less so, and on Windows the entire picture changes, because the Unix dependencies the project assumes do not exist there.

For a tool whose value is in the answers rather than the code, the build effort is a one-off cost, but it is a cost you pay before you can ask the first question.

The release naming is worth a second look, because it tells you how the project is versioned. The tags are build numbers rather than semantic versions, with 343 from 2024-08-06, 341 from 2024-08-01, and 304 from 2019-12-25, and the tag names carry the full commit hash they were built from, for example a build tagged with a long hash suffix.

A project that tags by build number with the commit embedded is a project where the exact source matters, which is consistent with a tool whose output is an answer about a specific piece of firmware and a specific device. The gap between 304 in December 2019 and 341 in August 2024, and then 343 a few days later, also tells you the release rate is irregular and that the number is a counter rather than a version, so there is no compatibility promise to reason about between builds.

For anyone tracking the project, the practical implication is to read the build number as an identifier rather than as a version, and to use the commit hash in the tag when you need to reproduce a specific result.

Editorial conclusion

tsschecker fits a device researcher who needs to answer a concrete question about Apple's signing servers, such as which builds are signed for which hardware, or who wants to explore how the TSS server responds across combinations of device and version. It does not fit a user who expects it to flash anything, because the tool reports status rather than installing firmware, and it does not fit anyone who needs a reliable way to produce reusable signing tickets, because the README says the collision methods are unreliable and points at other tools for that. Verify first that the device and firmware combination you are checking is one Apple still signs, that your system has the listed external libraries and the submodule, and that you read the nonce section carefully, because a ticket saved for one device is not usable on another once nonce entangling is in play.

Frequently asked questions

What does tsschecker check?

It checks the TSS signing status of various devices and firmware, meaning whether Apple will sign a given build for a given device. It also lists all devices, and all firmwares and OTA versions for a specific device, and it can explore Apple's TSS servers directly.

How do I check a specific firmware build with tsschecker?

You specify the BuildManifest.plist of the build, which is the metadata that describes it. The tool can also work without device specific values at all, and in that mode it can save blobs when given an ECID with the option to print the TSS response, although the README notes there are better tools for that.

What is nonce entangling and why does it matter for tsschecker?

On Apple A12 and newer devices, such as the iPhone XR and the Apple Watch Series 4, the nonce a device generates is also derived from its UID, so it is device specific. A ticket saved with such a nonce is only usable on the device that produced it, which is why the README says you need the nonce your device actually generates from your generator.

Are nonce collisions reliable in tsschecker?

The README says the collision method only works on a few firmwares and devices and is not reliable, and that recovery collisions occur only on a few iOS versions and stop working after an update. Device firmware update collisions are described as more reliable, occurring commonly on A7 and A8 chipsets regardless of the iOS version.

What does tsschecker need to build?

The external libraries libcurl, libfragmentzip, libirecovery, and libplist, plus OpenSSL or CommonCrypto on macOS, and the jssy submodule compiled as well. The build uses autotools, with a Makefile.am, a configure.ac, an autogen.sh script, and an Xcode project for macOS.

Official sources

  1. Issues
  2. License: LGPL-3.0
  3. README
  4. Releases
  5. tihmstar/tsschecker on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/tihmstar-tsschecker.svg)](https://hysenlabs.com/projects/tihmstar-tsschecker)

Was this useful?