github infosave2007/aivpn v1.0.3

latest releases: v1.1.0, v1.0.5, v1.0.4...
one month ago

⚠️ Upgrading from 1.0.0 or 1.0.1

The APK published with those releases was a debug build — signed with the
public Android debug key and marked android:debuggable, which let anyone with
adb access attach to the VPN process and read session keys out of its memory.
Releases since 1.0.2 are signed properly, so Android will refuse to install
this one over 1.0.0/1.0.1 ("App not installed" / signature mismatch).
Uninstall the old app first, then install this APK, then re-add your
aivpn:// key.
Upgrading from 1.0.2 works in place — same signing key.

Fixed

Roughly one connection key in five could never connect (#68, part of #70)

The client framed its handshake at the protocol default header length (20 bytes),
while the server reads the embedded ephemeral key at the eph_pub_offset of the
mask it matched. For quic_https_v2 that offset is 14, so the key landed six
bytes past where the server looked: wrong DH input, wrong session keys, and a tag
mismatch against every candidate of every registered client — permanently.

The PSK selects the preset (blake3(psk)[0] % 5), so this bricked about one
issued key in five at random: --show-client handed out a key the app could
never use, and the app sat in an endless reconnect — the "hangs after entering
the key" report. The other four presets have a 20-byte header, where the wrong
value happens to equal the right one, which is why it went unnoticed for so long.

Both mobile cores now frame with the handshake mask's own length and decode the
ServerHello at whichever length actually parses.

The data plane could use a different mask than the handshake

The handshake mask and the data mask were resolved by two separate calls. The
server pushes fresh bootstrap descriptors as soon as the session is up, so the
second call could see a newer descriptor set and pick a different candidate; if
its header length differed, the server decrypted every uplink packet at the wrong
offset while the resonance tag still matched — the tunnel showed "connected" and
carried nothing. The session now reuses the exact mask the handshake was accepted
with.

Server: client traffic was dropped on any host with Docker installed

Docker sets iptables -P FORWARD DROP, and netfilter evaluates the legacy
iptables FORWARD hook independently of the nftables ruleset, so a forwarded
packet must be accepted by both. With the nftables backend selected, client
packets reached the server's tun and never left it. The accepts are now mirrored
into iptables — into DOCKER-USER when present, which Docker never flushes —
whenever the FORWARD policy is DROP, and removed again on teardown. Hosts without
Docker are unaffected.

make android could publish a debug APK

With no signing material configured the build silently fell back to
assembleDebug, and that build shipped as the release asset in 1.0.0 and 1.0.1.
It now fails with an explanation instead; AIVPN_ALLOW_DEBUG_APK=1 restores the
old behaviour for local testing only.

Verified

On a Xiaomi 2203129G against a live server over the real internet, with a client
whose PSK selects quic_https_v2 — the case that could never connect before:
the handshake now validates, and three consecutive connect/disconnect cycles each
come back with the phone's egress IP equal to the server's and 0% loss (452 data
packets, no decrypt failures, no tag mismatches).

Not covered

The Windows half of #70 ("wintun adapter has no internet") was not investigated —
no Windows machine available. If your server predates 1.0.2, upgrade it first:
cross-version interoperability landed in 1.0.2 and covers that path.

Don't miss a new aivpn release

NewReleases is sending notifications on new releases.