Repository navigation
Conversation
There was a problem hiding this comment.
🟡 Changes recommended
Failed provisioning cleanup can permanently retain stale identity state, and the new Android profile is rendered with the wrong device icon.
3 open findings
What changed in this PR
Updates local Anisette to use an Android-consistent identity, enabling Grand Slam sign-in after Apple’s provenance checks changed.
Changes:
- Adds the Android hardware profile and migrates incompatible stored identities.
- Adds Apple Root CA G3 trust for provisioning.
- Extends the GSA probe and identity tests.
| File | Description |
|---|---|
scripts/probe_gsa_signin.py |
Adds real SRP-init probes. |
app/src/test/python/test_identity.py |
Tests Android identity bridging. |
app/src/main/res/xml/network_security_config.xml |
Trusts G3 for Apple endpoints. |
app/src/main/res/raw/apple_root_ca_g3.pem |
Adds Apple’s G3 root certificate. |
app/src/main/java/dev/wander/android/opentagviewer/anisette/LocalAnisette.java |
Migrates refused identities and provisioning. |
app/src/main/java/dev/wander/android/opentagviewer/anisette/AdiDeviceIdentity.java |
Defines Android as the default profile. |
app/src/androidTest/java/dev/wander/android/opentagviewer/anisette/LocalAnisetteIdentityTest.java |
Covers identity migration behavior. |
app/src/androidTest/java/dev/wander/android/opentagviewer/anisette/AdiDeviceIdentityTest.java |
Verifies Android profile composition. |
AGENTS.md |
Documents the provenance and trust constraints. |
🧠 Review effort: Balanced
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+291
to
+295
| ANDROID( | ||
| "Pixel 7", | ||
| "Pixel 7", "Android", "14", "UQ1A.240205.002", | ||
| "1404.0.5", "22.3.0", | ||
| "com.apple.akd/1.0") { |
Comment on lines
+471
to
+472
| if (path.exists() && !path.delete()) { | ||
| Log.w(TAG, "could not delete " + path + "; ADI may keep answering as the old machine"); |
Comment on lines
+269
to
+271
| verdict = _handler_verdict(answer.raw) if is_real_init else None | ||
| if verdict is None: | ||
| verdict = "refused" if answer.refused else "through" |
…here - --real-init builds the structurally real SRP init body that AsyncAppleAccount._gsa_authenticate sends (srp.User A2k over a synthetic, nonexistent Apple ID - init precedes any credential check, so this is still not a sign-in attempt) and reports the response plist's Status.ec/em - --anisette-json loads a provisioned cpd dump, --anisette-junk fills deterministic placeholders, --cpd-set/--cpd-unset vary single body fields - The edge probes remain untouched; the doc comment that described this mode as future work now describes what it found - With it, the 2026-10-12 refusal localises to one check: an Android-minted X-Apple-I-MD-M under a macOS client-info is refused ec=-80045 before OTP, serial or device-id are looked at; missing MD-M is -80009, malformed is -29004, missing OTP is -80010 - and an Android client-info over a freshly Android-provisioned machine id is answered ec=0 (issue parawanderer#248, xtool-org/xtool#337) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Since 2026-10-12 Grand Slam refuses SRP init (ec=-80045) when a machine id minted by Apple's Android ADI libraries is presented under a macOS or iPhone client-info - issue parawanderer#248, and every install of this app. - Hardware.ANDROID (Pixel 7 / Android 14 / UQ1A.240205.002, the string xtool verified in xtool-org/xtool#337) is the new DEFAULT; canSignIn() marks LEGACY_MAC and IPHONE as refused at the handler - LocalAnisette replaces a stored identity whose profile can no longer sign in and wipes files/anisette/provisioning before the library is opened, so ADI re-provisions under the Android claim - a Mac-provisioned machine id presented as Android is answered hsc=434. Costs affected installs one re-login; the alternative is an install that can never sign in again - profileToShow describes the profile the next load will actually use - Tests: AdiDeviceIdentityTest pins the Android client-info string and canSignIn(); LocalAnisetteIdentityTest covers keep-vs-replace and the provisioning wipe; test_identity.py pins that the six bridged values render as the verified client-info through FindMy.py's own composer Verified end to end: a freshly Android-provisioned machine id answers ec=0 via scripts/probe_gsa_signin.py --real-init, and on a Pixel 8 Pro this build downloads the libraries, provisions under the Android identity (ADIProvisioningEnd = 0) and signs in - password and 2FA accepted - through to the account step. 469 JVM tests, 46 pytest, 35 instrumented tests green. Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
rubo77
force-pushed
the
feature/gsa-real-init
branch
from
October 14, 2026 09:35
256f912 to
e82f0af
Compare
Whether an Android identity is handed searchPartyToken at all is the open question in parawanderer#248 and malmeloo/FindMy.py#278, and it can only be answered by looking at a live response - so a completed sign-in now logs the token names issued. In exportToString and after complete_login, the two points every successful login passes through. Names only: a token's value is a credential and must not reach a log; which names exist is the diagnostic. Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
… provenance Two stacked experiments around the delegate refusal that follows the -80045 fix: - _claimAppleMusicAtMobileme: the delegate request identifies as macOS accountsd/iCloudHelper while the identity claims Android - the same class of inconsistency Grand Slam rejects one layer earlier. Claiming com.apple.android.music instead produced status=1 unchanged on both a never-activated and an iCloud/Find My-activated account, so the header claim is not the gate. - loginSync forces the remote Anisette provider so the machine id presented is not minted by the local Android ADI libraries. Pending: whether status flips with a server-provisioned identity, which would locate the gate at ADI provenance itself. Experiment instrumentation, not a product change. Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
… names - [MOBILEME-PROBE] logs idms_pet/adsid/idms_hb lengths at the delegate step and the delegate response's top-level keys (values as str[NNN]). Result on both test accounts via server anisette: idms_pet_len=0, status-message='Authentication failed' - the request went out with an empty password; status=1 is mechanical, not an account gate. - [GSA-PROBE] logs hsc/au/ec per GsService2 step and, after decrypt_spd_aes_cbc, the spd keys and issued token names in t. au=None runs show no pet - consistent with the pet being minted only on the trusted-device challenge path (hoorayman: hsc=409 -> pet=523). - The decrypt hook patches findmy.util.crypto because account.py resolves it through the module attribute. Findings posted to parawanderer#248. Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Since 2026-10-12 Grand Slam refuses SRP init (ec=-80045) when a machine id minted by Apple's Android ADI libraries is presented under a macOS or iPhone client-info — every install of this app.
What this changes
Hardware.ANDROID(Pixel 7 / Android;14;UQ1A.240205.002 / com.apple.akd/1.0) is the default profile; LEGACY_MAC/IPHONE are marked unable to sign in.files/anisette/provisioningis wiped before the library opens, so ADI re-provisions under the Android claim. A Mac-provisioned machine presented as Android is answered hsc=434 — re-provisioning is required, not just a new string. Costs affected installs one re-login.gsd.apple.comchains to Apple Root CA - G3, absent from trust stores: added as an anchor for gsa/gsd. This is also the -45003/502 every public Anisette server hit.scripts/probe_gsa_signin.pygains--real-init: a structurally real SRP init (no credentials, synthetic account) that reports the handler's ec — the tool the refusal was localised with.Verified
ec=0from a freshly Android-provisioned machine id, live, via--real-initADIProvisioningEnd = 0), password + 2FA acceptedNot verified, stated plainly
After successful auth our test account hit
com.apple.mobilemestatus=1— the account-level wall of #221, unrelated to this fix but meaning a full login through to fetching awaits an account that clears it. Whether the Android claim changes mobileme's behaviour for previously-working accounts is unknown; it is the only claim that reaches that stage at all.Credit
The root-cause detail and the field-level probe matrix are in the issue comment on #248. Credit to xtool-org/xtool#337 for finding the client-info side independently.