app: scaffold echolot-app + core-protocol — client spine verified live vs fmr
Multi-module Android app, built bottom-up from a verifiable core. core-protocol is pure Kotlin/JVM (no Android SDK): SPKI-pinned control plane (enroll/profile/session over HttpsURLConnection — API-1 compatible, hostname verification off, trust is the pin), HKDF-SHA256 session keys, ELT1 UDP data plane (HMAC gate, ECHO+observation, MTU probe) — byte-compatible with the Go server. Unit tests incl. the RFC 5869 HKDF vector (key derivation provably matches the server). LiveServerTest + scripts/test-fmr.sh prove the client end-to-end against the deployed fmr server: profile (8 caps), session, ECHO rtt~11ms with the observation block returning our observed NAT port, MTU 1400->1400, observations. Live test self-skips without ECHOLOT_LIVE_*. Two client bugs caught live: java.net.http hostname verification (→ HttpsURLConnection, also the Android-minSdk-26 choice) and ECHO padding needed for the observation to survive anti-amplification. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
b229eeb674
commit
3520eabd21
@@ -0,0 +1,35 @@
|
||||
# Echolot app
|
||||
|
||||
The production Android client ([spec](../docs/)). Native Kotlin + Jetpack Compose. Multi-module;
|
||||
built bottom-up from a verifiable protocol spine.
|
||||
|
||||
## Modules
|
||||
|
||||
| Module | Type | Status |
|
||||
|---|---|---|
|
||||
| `core-protocol` | pure Kotlin/JVM | **done** — client half of `probe-protocol.md`, verified live against the server |
|
||||
| `core-measurement` | pure Kotlin/JVM | planned — `measurement-schema.md` types |
|
||||
| `core-probe` | Android lib | planned — app-tier probes, ported from `echolot-prober` |
|
||||
| `core-shizuku` | Android lib | planned — dual-path executor (UserService + newProcess fallback) |
|
||||
| `app` | Android app | planned — Compose UI |
|
||||
|
||||
`core-protocol` is deliberately Android-free so it builds and unit-tests on any JDK (no Android
|
||||
SDK) and can run **integration tests against a live server**.
|
||||
|
||||
## core-protocol
|
||||
|
||||
Implements the control plane (SPKI-pinned enrollment/profile/sessions via `HttpsURLConnection` —
|
||||
Android-API-1 compatible, hostname verification off because trust is the pin), the HKDF-SHA256
|
||||
session-key schedule, and the binary ELT1 UDP data plane (HMAC gate, ECHO + observation block,
|
||||
MTU probe) — byte-compatible with the Go server.
|
||||
|
||||
```sh
|
||||
./gradlew :core-protocol:test # unit tests (crypto vectors, wire round-trip)
|
||||
scripts/test-fmr.sh # live end-to-end test against the deployed server
|
||||
```
|
||||
|
||||
`test-fmr.sh` mints an enrollment token over SSH, enrolls via the public control plane, computes
|
||||
the SPKI pin from the served cert, and runs `LiveServerTest` — proving the client speaks the wire
|
||||
protocol to the real server (enroll → profile → session → echo+observation → MTU → observations).
|
||||
The live test self-skips when `ECHOLOT_LIVE_*` env vars are absent, so unit runs and CI stay green
|
||||
offline.
|
||||
Reference in New Issue
Block a user