A corecrypto-free implementation of Apple's GrandSlam (GSA) authentication, in C/C++ on OpenSSL.
libgsa reimplements the cryptography and the SRP-6a login handshake that
AltSign / AltServer use to authenticate with Apple's Developer-portal servers —
without Apple's corecrypto. It depends only on OpenSSL (already present in
every AltServer-Linux build) and, optionally, libplist. Drop it into an
AltSign-style codebase to delete the entire corecrypto fetch/compile/link
stage.
It is heavily inspired by JJTech0130/pypush,
whose Python implementation is the clearest public reference for exactly how the
GrandSlam SRP-6a variant behaves. libgsa reads pypush (and the other open
reimplementations below) as a specification — clean-room, no code copied — and
in fact validates its own output against the very same SRP library pypush
authenticates with live (see Correctness).
Status: integrated & deployed. The OpenSSL crypto primitives are implemented and covered by RFC/NIST test vectors. The Apple-variant SRP-6a client is proven byte-for-byte against a golden vector generated by the MIT
srplibrary (the same SRP code that authenticates live against Apple GrandSlam — see Correctness). libgsa now fully replaces Apple's corecrypto in the AltServer-Linux / AltSign-Linux build chain — the resulting binary linkslibgsa.ainstead oflibcorecrypto_static.a, carries zero corecrypto symbols, and runs on a live homelab signer. An A/B swap against the old corecrypto binary produced identical GrandSlam behaviour, so the replacement is integration-equivalent.
Every C/C++ AltServer-Linux fork still statically links Apple's corecrypto,
which:
- ships under Apple's corecrypto Internal Use License (90-day, internal-use, security-verification only, no redistribution) — so it can never be baked into a redistributable binary;
- is fetched live from
developer.apple.comat build time, and Apple silently revs it (it broke once already when the zip started extracting tocorecrypto-2024/).
There are reimplementations of this exact flow in Rust (SideStore
apple-private-apis), Python (JJTech0130 pypush) and D (Dadoum
Provision/Sideloader) — but none in C/C++. libgsa fills that gap so the
whole AltServer-Linux ecosystem can drop corecrypto.
Yes — this is the clean path, not the risky one.
- We do not ship, copy, or redistribute any Apple code.
corecryptosource is never vendored here. - We reimplement a protocol (GrandSlam SRP-6a) on standard, redistributable crypto (OpenSSL) using published specs — RFC 5054 (SRP), RFC 2945, RFC 6070 (PBKDF2), NIST AES/GCM. Protocols and APIs are not copyrightable (Google v. Oracle, 2021); only an implementation is, and this is an independent implementation.
- The open reimplementations are read as specification only (clean-room) — no source is copied — so this library keeps its own permissive license.
Caveat: this library talks to Apple's private auth servers, so Apple Developer Program terms govern your use of it (exactly as they do for AltStore / AltServer). That's a constraint on the operator, not a distribution problem with the code. Use a secondary Apple ID.
| Layer | What | Deps |
|---|---|---|
gsa/crypto.h |
SHA-256, HMAC, PBKDF2-HMAC-SHA256, AES-256-CBC+PKCS7, AES-256-GCM, constant-time compare | OpenSSL |
gsa/srp.h |
SRP-6a client, Apple variant (RFC 5054 2048-bit group, SHA-256, noUsernameInX, s2k/s2k_fo password hashing) |
OpenSSL |
gsa/gsa.h |
The GrandSlam handshake state machine (builds/parses the auth plists, derives session keys, decrypts spd/et, yields adsid + app token). Transport-injected — you supply the HTTP + anisette callbacks. |
libplist (optional) |
It deliberately does not include an HTTP client or an anisette/ADI provider —
those are injected by the caller — which keeps libgsa tiny and reusable.
(Anisette is a separate Apple dependency; replacing corecrypto does not
replace it.)
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build
ctest --test-dir build --output-on-failureOn macOS (Apple Silicon), point CMake at the arm64 Homebrew OpenSSL so it doesn't pick up an x86_64 one:
cmake -B build -DCMAKE_BUILD_TYPE=Release \
-DOPENSSL_ROOT_DIR="$(brew --prefix openssl@3)"Options:
-DGSA_BUILD_TESTS=ON(default) — build the vector/differential tests.-DGSA_DIFF_CORECRYPTO=/path/to/libcorecrypto_static.a— also build the differential harness that diffslibgsaSRP output byte-for-byte against Apple'scorecrypto(for local correctness validation only; never shipped).
Crypto is byte-deterministic, so this is testable without ever calling Apple:
- Primitive vectors (
tests/test_primitives.c) — PBKDF2 (RFC 6070), HMAC (RFC 4231), AES-CBC / AES-GCM (NIST KAT). Run in CI, no Apple, no network. - SRP Apple-variant exactness (
tests/test_srp.c) — every byte ofA, thes2kpassword key,M1, the session keyK, and the server proofM2is asserted against a frozen golden vector intests/vectors/apple_srp_vector.h. That vector is generated bytests/oracle/gsa_oracle.pyusing the MIT-licensedsrplibrary configured exactly as a GrandSlam client (rfc5054_enable()+no_username_in_x()) — the same SRP implementation that authenticates live against Apple's servers inpypush, so its numbers are ground truth without using any Apple code. The subtle Apple specifics this pins down: thenoUsernameInXflag drops the username fromxbut keeps the":"separator (x = H(s | H(":" | pwkey))); the real username is still folded intoM1viaH(I); andA/B/Senter the hashes as minimal big-endian bytes while onlyk/upad tolen(N). An optionalcorecryptodifferential (-DGSA_DIFF_CORECRYPTO) can cross-check on a self-hosted runner. - Recorded transcript replay (
tests/test_transcript.c) — replay one captured GSA handshake offline and assert the same session key / decrypted token, with zero Apple contact. - Live acceptance (manual) — build AltServer with
-lcorecrypto_staticremoved, authenticate with a test Apple ID, sign + launch on a device with noCode=85.
Apple ships corecrypto with no version handle and silently revs it. Two CI
signals catch that — neither one redistributes any Apple code:
- SHA-drift watch —
corecrypto-drift.ymlruns weekly, downloads Apple's source bundle only to checksum it, compares the SHA-256 to the pin incorecrypto.pin, discards the zip, and opens a tracking issue if it drifted. No build, no link, nothing persisted. - Behavioral differential —
corecrypto-differential.ymlactually buildscorecryptoand diffslibgsa's SRP/crypto output against it byte-for-byte. This is the oracle that says whether behavior (not just the source) changed.
Why the differential is self-hosted / local only. Apple's corecrypto
Internal Use License permits download + security verification but forbids
redistributing the source or the built archive. Using corecrypto to confirm
our reimplementation matches is security verification — that's allowed — but
the artifact must never leave a machine you control. So the differential
workflow runs on self-hosted runners only, is bring-your-own (it never
downloads corecrypto — you supply your Apple-fetched corecrypto.zip),
uploads nothing, and scrubs the local .a afterward. To run it yourself:
# 1) build corecrypto into a static archive (you accept Apple's license by doing so)
A=$(scripts/build-corecrypto-static.sh /path/to/your/corecrypto.zip)
# 2) build + run libgsa's differential against it
cmake -B build-diff -DCMAKE_BUILD_TYPE=Release -DGSA_DIFF_CORECRYPTO="$A"
cmake --build build-diff
ctest --test-dir build-diff --output-on-failure -R srpThe golden vectors committed under tests/vectors/ are the outputs of one
such local run (just numbers — not Apple code), so the public test suite keeps
proving libgsa matches the last validated corecrypto behavior with zero
Apple code present.
libgsa stands on the shoulders of the people who reverse-engineered and
documented Apple's GrandSlam flow in the open. We read their work as a
specification — no source was copied — but this library would not exist without
it:
- JJTech0130 / pypush — the primary
inspiration for this project and the clearest public reference for the GSA
SRP-6a variant (
rfc5054_enable()+no_username_in_x(), thes2k/s2k_fopassword hashing, and the session-key derivation). Its choice of the MITsrplibrary is also what makes our golden-vector oracle possible. - SideStore / apple-private-apis (
icloud-auth, MPL-2.0) — Rust analogue. - Dadoum / Provision + Sideloader — D reimplementation.
- The AltStore project (NyaMisty's AltSign-Linux) — the original corecrypto-based flow this replaces.
MIT — see LICENSE.