Skip to content

feat: add Shizuku-based RKP root registration toggle#13

Open
shoey63 wants to merge 7 commits intoVisionR1:masterfrom
shoey63:rkp-reg
Open

feat: add Shizuku-based RKP root registration toggle#13
shoey63 wants to merge 7 commits intoVisionR1:masterfrom
shoey63:rkp-reg

Conversation

@shoey63
Copy link

@shoey63 shoey63 commented Mar 19, 2026

Description

This PR introduces the ability to Register or Unregister the device for the Google KeyMint V3 root directly from the app's UI, and introduces a raw RKP certificate chain diagnostic tool. This removes the manual dependency on external Python scripts or desktop-based ADB commands, allowing for a mobile-native workflow.

Key Features

  • Native Shizuku Integration: Implemented RkpRegistrationManager.kt to execute cmd remote_provisioning HAL commands via Shizuku.
  • Reflection-Based Bypass: Cleanly bypasses the recent private restriction on Shizuku's newProcess API, ensuring a lightweight implementation without the overhead of a full User Service.
  • Coroutines & Network Logic: Wrapped the Google RKP backend POST requests in Kotlin Coroutines to ensure the UI remains responsive while processing the Certificate Signing Request (CSR).
  • Raw RKP Chain Dumping: Added a "Dump RKP Chains" utility to the overflow menu (requested by @zgfg on XDA). It captures the raw PEM output from both the default and strongbox HALs and pipes it directly into the Android Share Sheet for instant forum sharing.
  • ProGuard Optimized: Includes critical -keep rules for Shizuku to ensure reflection logic survives R8 minification in Release builds.

⚠️ Crucial Testing Note (The Factory Reset Bypass)

Android's Remote Key Provisioning Daemon (RKPD) aggressively caches certificates. After toggling the state in the app, the system will serve cached certificates until the pool is exhausted.

Previously, Google's documentation stated a Full Factory Reset was required to clear these if you didn't have raw root access. This is no longer true.

Because Shizuku runs via ADB (UID 2000), it holds the CLEAR_APP_USER_DATA permission natively. This implementation leverages Shizuku to silently execute:

pm clear com.google.android.rkpdapp (or com.android.rkpd on AOSP)

This safely flushes the daemon's cache and forces an immediate fetch from Google's servers, completely bypassing the factory reset requirement.

Testing Results

  • Unregister: Verified that unregistering, clearing RKPD cache via Shizuku, and forcing a fetch successfully downgrades the system to the legacy Google hardware attestation root (RSA).
  • Register: Verified that registering, clearing cache, and forcing a fetch successfully upgrades the system to the new Key Attestation CA1 (ECC) root.
  • Dump RKP: Verified the raw InputStream from the HAL is captured and successfully passed to Intent.ACTION_SEND.
  • Release Build: Confirmed the overflow menu and Shizuku logic work perfectly in a minified Release APK.

💬 Important Clarification
Root is NO LONGER required for this feature. Because we shifted the pm clear execution to Shizuku rather than relying on su -c, non-rooted users can safely toggle their RKP state and clear the stuck daemon cache without fear of bricking their attestation state or needing a factory reset.

@VisionR1
Copy link
Owner

About this:

The "Non-Root" Risk: Using these toggles on a locked/non-root device is dangerous. Because a non-root user cannot execute the pm clear commands needed to flush the RKP certificate cache after unregistering, the device may get stuck in an inconsistent attestation state. In such cases, a Full Factory Reset is the only way to recover original functionality.

Should have a warning ?

Example:

This will modify the system's Remote Key Provisioning state. If you are not rooted, you may not be able to revert this change without a factory reset. Proceed?

@shoey63
Copy link
Author

shoey63 commented Mar 19, 2026

Good point. To clarify: technically, these commands will fail to execute via Shizuku on a non-rooted device anyway due to permission restrictions on the cmd shell. However, I agree that a 'Proceed' warning dialog is a much better UX than just letting a user click a button and seeing a 'Failure' toast. I'll update the PR to include a confirmation dialog with that warning text

fix: add confirmation dialog and resolve Data import.
@shoey63
Copy link
Author

shoey63 commented Mar 20, 2026

Updated with warning.
Screenshot_20260320-171012

@shoey63
Copy link
Author

shoey63 commented Mar 20, 2026

Hold on. I'm testing a clear cache enhancement so you can switch back and forth while still in the app.

@shoey63
Copy link
Author

shoey63 commented Mar 20, 2026

Actually these features will be useless in a few weeks when RKP goes fully live. Feel free to close the PR if you like

@VisionR1
Copy link
Owner

Actually these features will be useless in a few weeks when RKP goes fully live. Feel free to close the PR if you like

Oh, and you did so much work.

@shoey63
Copy link
Author

shoey63 commented Mar 20, 2026

Actually these features will be useless in a few weeks when RKP goes fully live. Feel free to close the PR if you like

Oh, and you did so much work.

It's mainly for my personal experiments. I'm thinking of the work you have to do to revert everything once it's redundant, plus now more translations.
I'll add the final commit and you can decide.

@VisionR1
Copy link
Owner

VisionR1 commented Mar 20, 2026

Actually these features will be useless in a few weeks when RKP goes fully live. Feel free to close the PR if you like

Oh, and you did so much work.

It's mainly for my personal experiments. I'm thinking of the work you have to do to revert everything once it's redundant, plus now more translations. I'll add the final commit and you can decide.

Understand.

Oh yeah, right.

If only need few weeks, if 1 year then yes.

Keeping open, maybe Google change time, and RKP goes fully live after more.

feat: automate RKPD cache clearing on successful RKP state change
@shoey63
Copy link
Author

shoey63 commented Mar 20, 2026

Final commit pushed.

Register RKP root -> RKP test = new root
UnRegister RKP root -> RKP test = old root again.

All instant without leaving the app.

Is it ok to put my unsigned ci release build in your TrickyStore XDA thread?

For anyone following.
https://github.com/shoey63/KeyAttestation/actions/runs/23343785222

@VisionR1
Copy link
Owner

Final commit pushed.

Register RKP root -> RKP test = new root UnRegister RKP root -> RKP test = old root again.

All instant without leaving the app.

Is it ok to put my unsigned ci release build in your TrickyStore XDA thread?

For anyone following. https://github.com/shoey63/KeyAttestation/actions/runs/23343785222

Yeah, sure put it.

@shoey63 shoey63 closed this Mar 21, 2026
@shoey63 shoey63 deleted the rkp-reg branch March 21, 2026 06:08
@shoey63 shoey63 restored the rkp-reg branch March 21, 2026 06:30
@shoey63 shoey63 reopened this Mar 21, 2026
@shoey63
Copy link
Author

shoey63 commented Mar 22, 2026

Some changes

  • Root is NO LONGER required for this feature. Because we shifted the pm clear execution to Shizuku rather than relying on su -c, non-rooted users can safely toggle their RKP state and clear the stuck daemon cache without fear of bricking their attestation state or needing a factory reset.

  • Added a "Dump RKP Chains" utility to the overflow menu (requested by @zgfg on XDA)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants