Commit Graph
19 Commits
Author SHA1 Message Date
Enginex0 ac9641ed2a feat(pki): integrate native cert gen with BouncyCastle fallback
NativeCertGen.kt provides CertGenConfig data class and JNI bridge
to libcertgen.so. KeyMintSecurityLevelInterceptor.doSoftwareKeyGen()
tries native path first, falls back to BouncyCastle on failure or
when library unavailable. App.kt loads libcertgen.so at daemon start.
2026-03-09 16:23:09 +01:00
Enginex0 c87759c6c3 feat(native-certgen): implement JNI bridge with panic-safe entry points
Three JNI exports: generateAttestedKeyPair (orchestrates keygen,
attestation, certbuilder, returns length-prefixed binary),
initLogging (multi-output tracing setup), dumpLogs (diagnostic ZIP).
CertGenConfig extraction via typed JNI field accessors. catch_unwind
on all FFI boundaries.
2026-03-09 16:13:41 +01:00
Enginex0 76b18706f1 fix(native-certgen): address Phase 3 validation findings
Remove ENCRYPT/VERIFY from KeyUsage mapping to match Kotlin behavior.
Document BasicConstraints and SKI suppression via rcgen NoCa default.
Fix rotating log off-by-one that kept one extra backup file. Handle
BMPString (UTF-16BE) and VisibleString in X.500 DN parser.
2026-03-09 16:08:07 +01:00
Enginex0 e76f5115e0 feat(native-certgen): implement X.509 certificate chain builder
Builds v3 leaf certificate with attestation extension and KeyUsage,
signs with keybox private key via rcgen 0.13.2. Assembles full chain
(leaf + keybox intermediates + root). Supports EC and RSA keybox
signing keys. Uses rcgen's signed_by() with a synthesized issuer
Certificate — no manual DER fallback needed.
2026-03-09 15:55:15 +01:00
Enginex0 0725aed094 feat(native-certgen): implement logging subsystem
Multi-output logging via tracing: /dev/kmsg for logcat, rotating file
appender (512KB, 3 files), stderr for debug. Diagnostic ZIP dump with
log files and TEE status snapshots. Verbose toggle via JNI flag or
.verbose marker file.
2026-03-09 15:41:46 +01:00
Enginex0 9d61af6ce8 feat(native-certgen): implement ASN.1 attestation extension encoder
DER encoder for Android KeyMint attestation extension (OID
1.3.6.1.4.1.11129.2.1.17). SecurityLevel and VerifiedBootState as
ENUMERATED, EXPLICIT context-specific tagging with long-form for
tags >= 31, sorted AuthorizationList fields, RootOfTrust with
BOOLEAN TRUE=0xFF, SET OF INTEGER with DER sort, DO_NOT_REPORT
sentinel omission.
2026-03-09 15:32:31 +01:00
Enginex0 7863e8dd17 fix(native-certgen): address Phase 0-1 validation findings
EC keygen now returns proper SPKI DER instead of raw point bytes.
RSA keygen uses caller-supplied exponent via new_with_exp() and
validates key size to 2048/3072/4096. Keybox parser extracts leaf
subject DN (not issuer). Added AttestKey=7 to KeyPurpose. Realigned
error variants with spec.
2026-03-09 15:21:33 +01:00
Enginex0 f840eed42b feat(native-certgen): implement keybox DER certificate chain parser
Splits concatenated DER cert chains into individual certificates,
extracts leaf issuer DN and notAfter via x509-cert crate. Handles
multi-byte DER length encoding (0x81-0x84).
2026-03-09 15:09:29 +01:00
Enginex0 4c7f0a09ea feat(native-certgen): scaffold Rust crate with foundation types and keygen
Cargo.toml with 16 dependencies per build spec, error types with
From impls for all upstream error types, CertGenParams mapping the
full JNI config contract, EC/RSA key generation via ring and rsa crates.

Compiles clean for aarch64-linux-android via cargo-ndk.
2026-03-09 15:05:25 +01:00
Enginex0 4971f7b4a5 Derive boot and vendor patch levels from system prop when system=prop
TrickyAddon fetches Pixel bulletin dates for boot/vendor but system=prop
resolves to the real device prop, creating a cross-component date mismatch
on non-Pixel devices. Force all three through the same prop resolution path.
2026-02-07 00:47:53 +01:00
Enginex0 9ea39f0545 Rate-limit per-UID hardware keygen and harden importKey eviction
Sliding window limits each UID to 2 hardware generateKey calls per
30s burst window with max 2 concurrent. Overflow falls back to
software cert generation.

importKey post-hook retains patched chains instead of full eviction,
preventing detectors from using generate-then-import to bypass
attestation patching. getKeyEntry serves retained chains for imported
keys that overwrote attested aliases.
2026-02-07 00:47:47 +01:00
Enginex0 c332f8ad0d Cap interceptable binder payload size at 256KB
Prevents thread starvation from flood attacks targeting the
binder interceptor with oversized payloads.
2026-02-07 00:47:42 +01:00
Enginex0 d76e6abeed Add file-level locking to prevent race conditions in key persistence
Per-key ReentrantLock prevents concurrent writes to same key file
2026-02-07 00:47:36 +01:00
Enginex0 142fe7bf13 Reject oversized aliases to prevent binder buffer exhaustion
MAX_ALIAS_LENGTH (256KB) with 4x safety margin for transaction overhead
2026-02-07 00:47:31 +01:00
Enginex0 e41a679928 fix(pki): strip HTML comments from PEM blocks before parsing
Some upstream keybox sources inject HTML comments inside PEM
certificate blocks. BouncyCastle's PEMParser chokes on these
non-base64 lines, silently failing to load the keybox.

Filter lines starting with <!-- in trimLines() before the content
reaches the PEM parser.
2026-02-07 00:47:26 +01:00
Enginex0 209d5c8902 fix(config): prevent FileObserver NPE on config file deletion
When a config file is deleted, the event handler sets file=null but
then force-unwraps it with file!! in the when block, crashing the
FileObserver thread. All subsequent config change notifications are
silently lost.

Replace force-unwrap with safe call, log a warning on deletion.
2026-02-07 00:47:20 +01:00
Enginex0 3817b37e18 Integrate key persistence with interceptors
Save keys on generation, restore on daemon startup, delete on cleanup.
Re-persist when cert chain updates via updateSubcomponents.
2026-02-07 00:47:16 +01:00
Enginex0 53ae250fc7 Add generated key persistence layer
Persist GENERATE-mode keys to disk so they survive daemon restarts.
Binary format with version header, atomic write via tmp+rename.
2026-02-07 00:47:10 +01:00
Enginex0 34ad97366e feat(module): add supervisor daemon with leak-safe restart and lifecycle scripts
Fork-based supervisor ensures the interceptor process survives crashes.
pingBinder() liveness check on pre-transact returns DEAD_OBJECT to
callers when interceptor is down, preventing real TEE state from leaking
during the restart window.

action.sh clears persistent key storage via KSU Action button.
uninstall.sh kills daemon processes and removes module artifacts while
preserving target.txt and keybox configuration.
2026-02-07 00:47:04 +01:00