Commit graph

58 commits

Author SHA1 Message Date
Sirius DevOps
411194a8b2
test(sdk): reproduce rustls CryptoProvider panic from the device
RED. The APK builds, installs and opens, but the first rustls config built
from the process default panics one call deep inside Arti's rustls backend:

    Could not automatically determine the process-level CryptoProvider from
    Rustls crate features.
    Call CryptoProvider::install_default() before this point ...

rustls 0.23 picks its provider from its own 'ring' / 'aws-lc-rs' crate
features, not from which crypto crates happen to be linked. Arti reaches
rustls via tor-rtcompat with default-features = false, so neither provider
feature is on and rustls compiles with zero providers. 'ring' does appear in
cargo tree, pulled in by snow for Noise -- unrelated and irrelevant.

This commit adds rustls as an explicit dependency with no provider feature
(no behaviour change: it is already in the graph that way) so the test can
name the type, plus the regression test. On the host it reproduces the
device's panic verbatim.

The SDK lockfile is resynced with the root Cargo.toml on main (onionwire
0.2.1, rpassword, md-5, rtoolbox) in the same commit so the test build is
against a consistent lock.
2026-09-10 22:02:02 -04:00
389d8f16c4 Merge pull request 'fix(cli): hide store passphrase like a password prompt' (#14) from feat/hidden-store-passphrase into main
All checks were successful
ci / test (push) Successful in 3m32s
Reviewed-on: #14
2026-09-10 21:18:46 -04:00
b354632552 Merge branch 'main' into feat/hidden-store-passphrase
All checks were successful
ci / test (pull_request) Successful in 3m44s
2026-09-10 21:18:32 -04:00
Sirius DevOps
c5019f1737
fix(cli): hide store passphrase like a password prompt
All checks were successful
ci / test (pull_request) Successful in 4m54s
stdin read_line echoed the passphrase. rpassword disables tty echo.
ONIONWIRE_STORE_PASSPHRASE still skips the prompt.
2026-09-10 21:10:50 -04:00
2abb9af4ad Merge pull request 'chore: bump crate version to 0.2.1' (#13) from feat/v0.2.1 into main
All checks were successful
ci / test (push) Successful in 5m10s
Reviewed-on: #13
2026-09-10 21:08:20 -04:00
Sirius DevOps
51e47ff90c
chore: bump crate version to 0.2.1
All checks were successful
release / aarch64 (push) Successful in 5m19s
ci / test (pull_request) Successful in 5m34s
Tag and --version have to move together. Ships the post-v0.2.0 main
line: security audit F1–F7, Pi CI serialize, Android SDK already on main.
2026-09-10 20:52:24 -04:00
f109223678 Merge pull request 'fix: security audit F5–F7 + Pi CI races (bundle)' (#12) from feat/audit-fixes-bundle into main
All checks were successful
ci / test (push) Successful in 2m45s
Reviewed-on: #12
2026-09-10 20:41:40 -04:00
Sirius DevOps
08ced86a34
Merge F5 wallet digest RPC onto audit bundle
All checks were successful
ci / test (pull_request) Successful in 3m33s
Keep sha3 (F4 checksums) and md-5 (HTTP Digest). Threat model: digest login
plus conjunctive verified receipts. Wallet tests: F1 matcher fixtures plus
F5 digest/cap coverage.
2026-09-10 20:36:10 -04:00
Sirius DevOps
39e7b3bf16
Merge remote-tracking branch 'origin/wt/t_792593f3' into feat/audit-fixes-bundle 2026-09-10 20:33:50 -04:00
Sirius DevOps
424002c0f5
[verified] fix(hs): redact onion in publish logs; cache 0700
All checks were successful
ci / test (pull_request) Successful in 3m0s
wait_until_published now logs HsId via safelog, not the locator.
Store and client_config mkdir Arti cache/state 0700. Arti
dangerously_trust_everyone stays on storage only.
2026-09-10 20:30:18 -04:00
Sirius DevOps
45c105de8a
fix(store): drop payments on /wipe; document non-forensic
All checks were successful
ci / test (pull_request) Successful in 3m1s
/wipe now deletes payments as well as chat, checkpoints WAL, and
enables sqlite secure_delete (flash still not crypto-shred).
2026-09-10 20:22:31 -04:00
Sirius DevOps
125aafb816
[verified] feat(wallet): require RPC digest login and cap reads
All checks were successful
ci / test (pull_request) Successful in 3m8s
Refuse unauthenticated ONIONWIRE_WALLET_RPC, speak HTTP Digest like
monero-wallet-rpc --rpc-login, cap responses at 1 MiB, and reject
.onion RPC URLs instead of half-dialing them over TCP.
2026-09-10 20:17:25 -04:00
Sirius DevOps
bfd28fce6b
fix(ci): serialize Pi jobs; valid XMR fixture after F4
All checks were successful
ci / test (pull_request) Successful in 2m49s
Overlapping Actions used a fixed docker name onionwire-ci (Conflict)
and OOM-killed with 137. Unique run_id names + one-at-a-time
concurrency. F1 ingest test still used 8+B*94 which F4 checksums reject.
2026-09-10 20:12:41 -04:00
b3c5b78f25 Merge pull request 'fix(pay): checksum Monero addresses (base58 + keccak)' (#7) from wt/t_45d30b55 into main
Some checks failed
ci / test (push) Failing after 3m13s
Reviewed-on: #7
2026-09-10 20:03:10 -04:00
2041302da7 Merge branch 'main' into wt/t_45d30b55
Some checks failed
ci / test (pull_request) Failing after 12s
2026-09-10 20:02:59 -04:00
Sirius DevOps
666b9d2e86
fix(pay): checksum Monero addresses (base58 + keccak)
All checks were successful
ci / test (pull_request) Successful in 3m16s
Reject prefix+length junk so /pay, /tip, and profile save cannot
sign or store garbage xmr_addr. Empty profile address stays allowed.
2026-09-10 20:01:45 -04:00
a56029b750 Merge pull request 'fix(qr): bind invite sig fields; cap decode' (#6) from wt/t_8b24e067 into main
All checks were successful
ci / test (push) Successful in 3m15s
Reviewed-on: #6
2026-09-10 19:52:12 -04:00
deee357772 Merge branch 'main' into wt/t_8b24e067
Some checks failed
ci / test (pull_request) Failing after 24s
2026-09-10 19:51:58 -04:00
Sirius DevOps
68da7fec3b
[verified] fix(qr): bind invite sig fields; cap decode
Some checks failed
ci / test (pull_request) Failing after 54s
Reject non-32-byte spk, non-v3 onion, and invites over 4KiB before
hex alloc. Sign onionwire-invite-v1 with 0x00 separators; verify that
first. Well-formed v1 concat still verifies after field checks.
2026-09-10 19:52:44 -04:00
b1427041c2 Merge pull request 'fix(store): bind chat AEAD to row AAD' (#5) from wt/t_69a6b3f9 into main
All checks were successful
ci / test (push) Successful in 3m4s
Reviewed-on: #5
2026-09-10 19:41:57 -04:00
Sirius DevOps
f75c434db7
[verified] fix(store): bind chat AEAD to row AAD
Some checks failed
ci / test (pull_request) Failing after 2m59s
ChaCha20-Poly1305 at rest now MACs owmsg1||friend_id_le64||dir||0x00||row_id_le64.
Swapped ciphertext fails closed. Empty-AAD v0.2 blobs rewrap once on unlock;
list_messages never falls back to empty AAD.
2026-09-10 19:41:00 -04:00
bdea9578e4 Merge pull request 'fix(wallet): conjunctive receipt verify' (#4) from wt/t_70fc1f81 into main
All checks were successful
ci / test (push) Successful in 2m56s
Reviewed-on: #4
2026-09-10 19:28:14 -04:00
Sirius DevOps
1a465581c2
[verified] fix(wallet): conjunctive receipt verify
Some checks failed
ci / test (pull_request) Failing after 35s
Require non-empty txid AND amount AND address against one
get_transfers row. Signed rcp alone never sets verified=1.
2026-09-10 19:29:39 -04:00
0dfd807b10 Merge pull request 'docs: security audit of 2b42864 (report only)' (#3) from wt/t_d85060fb into main
All checks were successful
ci / test (push) Successful in 3m8s
Reviewed-on: #3
2026-09-10 19:16:58 -04:00
95b0fa4dee Merge pull request 'feat(android): SDK AAR (UniFFI) + Compose APK, Arti rustls feature split' (#2) from wt/t_b7176a1b into main
All checks were successful
ci / test (push) Successful in 3m3s
Reviewed-on: #2
2026-09-10 19:16:44 -04:00
Sirius DevOps
dfa4ea8f39
docs: security audit of 2b42864 (report only)
All checks were successful
ci / test (pull_request) Successful in 2m57s
Evidence-backed audit at docs/SECURITY_AUDIT.md. No src/ changes.
2026-09-10 18:54:40 -04:00
apk-dev
672f2c9990
feat(android): SDK AAR (UniFFI) + Compose APK, Arti rustls feature split
All checks were successful
ci / test (pull_request) Successful in 3m22s
Adds the Android product alongside the existing Linux TUI, in one repo.

SDK — crates/onionwire-sdk is a UniFFI facade over the very same `onionwire`
crate the TUI runs on. Identity, invite, friend upsert, send/receive, rotate
and wipe all delegate; no protocol is reimplemented, so an Android peer and a
Linux peer interoperate. It is its own Cargo workspace because Arti's TLS
backends are non-additive: the TUI keeps native-tls (OpenSSL), Android needs
rustls + static-sqlite (no OpenSSL, no system libsqlite3 in the NDK).

android/ — Gradle project. :sdk produces the AAR (Kotlin bindings generated at
build time + libonionwire_sdk.so via cargo-ndk), :app is a Kotlin/Compose/M3
messenger depending on :sdk only. minSdk 26, targetSdk/compileSdk 36,
INTERNET-only, data in filesDir, backups excluded.

Root Cargo.toml grows `native-tls` (default) and `rustls` features so exactly
one Arti TLS backend is selected per build graph. The default build is
unchanged: same backend, ratatui still a normal dependency, src/tui.rs
untouched.

Also: Store::self_fingerprint/set_petname + Node wrappers (additive only),
scripts/build-android-local.sh, README sections, .gitignore for local SDK paths.
2026-09-10 18:20:19 -04:00
2b42864eba Merge pull request 'feat(store): encrypt chat bodies at rest; Ctrl-Q CLEAR/QUIT' (#1) from wt/t_b0456c4b into main
All checks were successful
ci / test (push) Successful in 2m44s
release / aarch64 (push) Successful in 5m33s
Reviewed-on: #1
2026-09-10 17:29:45 -04:00
Sirius DevOps
6323619d80
feat(store): encrypt chat bodies at rest; Ctrl-Q CLEAR/QUIT
All checks were successful
ci / test (pull_request) Successful in 3m13s
Wrap a random 32-byte message key with Argon2id+ChaCha20-Poly1305.
sqlite messages.plaintext is nonce||ciphertext; identity keys stay
plaintext. Empty/wrong passphrase fails closed. Ctrl-Q types CLEAR or
QUIT then Enter (Esc cancels).
2026-09-10 17:19:50 -04:00
Sirius DevOps
1d7f8e1f35
docs: v0.2 status — invite string, no QR graphic
All checks were successful
ci / test (push) Successful in 2m43s
README lede and F2/F3 now match the TUI: share/paste onionwire:v1
invite, no terminal QR.
2026-09-10 17:02:34 -04:00
Sirius DevOps
4fb47444d5
[verified] feat(tui): drop unicode QR, share onionwire:v1 invite
Some checks failed
ci / test (push) Has been cancelled
F2 shows the invite string with fp/onion hints instead of a terminal QR.
Keep encode/decode and F3 paste; drop the qrcode crate.
2026-09-10 16:53:03 -04:00
Sirius DevOps
e902a9041d
fix(hs): probe onion reachability instead of waiting on Bootstrapping
All checks were successful
ci / test (push) Successful in 2m59s
Arti combined status stays Bootstrapping through a 5 min HsDir upload
round. Treat a successful connect as published, floor cbtinitialtimeout
with cbtmintimeout at 20s, and skip preemptive 80/443 circuits so IPT
and HsDir builds are not starved. PUBLISH_WAIT stays 360s fail-closed.
2026-09-10 16:14:10 -04:00
Sirius DevOps
e63203ff56
feat: incoming rate limit, identity backup, v0.2.0
All checks were successful
ci / test (push) Successful in 4m11s
App-level token bucket on rend accepts (30/60s, burst 10), panic-safe TUI restore, sqlite WAL + integrity_check fail-closed. Encrypted owbak1 identity backup/restore. README and threat model cover profile, XMR sidecar, backup, mixed-version frames.
2026-09-10 14:50:01 -04:00
Sirius DevOps
1a9b54d138
feat: Monero invoice/receipt frames, wallet RPC, /pay /tip
All checks were successful
ci / test (push) Successful in 2m50s
Signed inv/rcp codecs keyed by identity, payments table with unverified
incoming receipts, optional JSON-RPC sidecar (loopback/.onion HTTP only),
and TUI /pay /tip. OnionWire still holds no spend keys.
2026-09-10 14:37:43 -04:00
Sirius DevOps
d304cc4c3b
feat: signed friend profile frames and TUI /profile /who
Some checks failed
ci / test (push) Waiting to run
release / aarch64 (push) Failing after 14m14s
prf frames are ed25519-signed, friend-visible only (unknown pubkey is ignored).
/profile edits self; F5 and /who show the selected friend's last profile.
2026-09-10 14:25:31 -04:00
Sirius DevOps
ef78be4035
fix(release): refuse to publish 0-byte assets + log on-disk sizes
Some checks failed
ci / test (push) Has been cancelled
Run 309 reported success but uploaded 0 bytes for both aarch64 assets
(a 0.85s 'upload' of an 18MB file). The Pack step had just listed
18258736 bytes and sha256sum -c'd OK, so the failure is in the handoff,
not the build.

- publish-release.sh now fails loudly on a 0-byte asset instead of
  publishing a release that silently breaks every download
- the workflow logs pwd, GITHUB_WORKSPACE, ls -l dist/ and the byte count
  of each dist file immediately before publishing

Ruled out: the api_curl retry wrapper. Reproduced from inside a
node:20-bullseye container (curl 7.74, same as CI) — wrapper and plain
curl both uploaded 994 bytes correctly through Cloudflare.
2026-09-10 14:20:45 -04:00
Sirius DevOps
c9d85d9ae5
feat: drop unknown typed frames instead of storing as chat
Some checks failed
ci / test (push) Has been cancelled
release / aarch64 (push) Failing after 2m8s
Classify decrypted plaintext before append_message so loc/prf/inv/rcp/png
and unknown xxx[space] prefixes never land in the message log.
2026-09-10 14:18:06 -04:00
Sirius DevOps
cbbf3f6baa
fix(release): harden publish curl against Cloudflare HTTP/2 stream errors
All checks were successful
ci / test (push) Successful in 6m1s
The dispatched v0.1.1 build succeeded a third time (2m06s, valid ARM ELF)
and then died at the first API call inside the publish step with curl exit
92 (HTTP/2 stream error) — job containers reach Forgejo through Cloudflare,
where that is intermittent.

- all API calls go through api_curl: --http1.1 --retry 5
  --retry-all-errors --retry-delay 3 --connect-timeout 20 --max-time 300
- HTTP/1.1 is the documented workaround for this instance's HTTP/2 resets

Job containers cannot reach http://forgejo:3000 (isolated GITEA-ACTIONS
network, name unresolvable, container IP unroutable — measured), so the
public hostname plus retries is the available fix.

Verified locally: create + idempotent re-run against a throwaway tag, both
clean; test release and tag deleted.
2026-09-10 14:08:39 -04:00
Sirius DevOps
9441bccf58
fix(release): tooling checkout so old tags can publish; never move a tag
Some checks failed
ci / test (push) Successful in 5m46s
release / aarch64 (push) Failing after 5m46s
The dispatched build of v0.1.1 kept failing at publish with
'scripts/publish-release.sh: No such file or directory' — the workflow is
read from the dispatch ref (main) but the workspace was the v0.1.1 tag,
whose tree predates scripts/ and .forgejo/.

- second checkout of the workflow's own ref into .ci-tools; publish runs
  .ci-tools/scripts/publish-release.sh (and .ci-tools/scripts/release-body.md)
- exclude ./.ci-tools from the build context tar
- target_commitish is now opt-in in publish-release.sh and only set for a
  push event, so a re-publish can never move an existing tag

Verified locally end-to-end against a throwaway tag: create, idempotent
re-run (stale assets deleted + replaced), public download, sha256sum -c,
--version. Test release and tag deleted afterwards.
2026-09-10 13:58:46 -04:00
Sirius DevOps
154bed7823
fix(ci): clippy clean on tests/hs.rs + pin step cwd to GITHUB_WORKSPACE
Some checks failed
ci / test (push) Successful in 3m47s
release / aarch64 (push) Failing after 5m25s
Two separate breakages from the first green-ish CI run:

1. tests/hs.rs asserted on a constant, which clippy rejects under
   -D warnings (clippy::assertions_on_constants) because the compiler
   folds the assert away. Compare through a runtime binding instead.

2. The release workflow built the aarch64 binary fine (13m02s, verified
   ARM ELF) but the publish step died with:
       /var/run/act/workflow/3: line 6: scripts/publish-release.sh: No such file or directory
   run: steps execute with act's cwd, not the repo root, so relative
   paths miss. Pin every run step with cd "${GITHUB_WORKSPACE}" (the
   pattern the osint-dashboard workflow already relies on).

Verified locally before pushing: cargo test 41 passed, cargo clippy
--all-targets -- -D warnings clean.
2026-09-10 13:50:57 -04:00
Sirius DevOps
7701f61c71
hs: wait 360s for HsDir publish; floor cbtmintimeout at 10s
Some checks failed
ci / test (push) Failing after 6m21s
180s fail-closed cut a working descriptor upload while status was still
Bootstrapping. Learned CBT can also drop to ~1s and kill HsDir circuits.
2026-09-10 13:43:23 -04:00
Sirius DevOps
d4fb93c27e
git: ignore /.worktrees/ (kanban worktrees live there)
All checks were successful
ci / test (push) Successful in 3m41s
2026-09-10 13:30:11 -04:00
Sirius DevOps
a278e71627
ci: install the clippy component in the rust image
Some checks failed
ci / test (push) Has been cancelled
rust:1.91-bookworm ships without clippy, so the clippy step died with
'cargo-clippy is not installed for the toolchain' after all 39 tests
passed. Also pushes the watcher fix (1=success 2=failure in Forgejo job
statuses, not action_run's numbering).
2026-09-10 13:24:59 -04:00
Sirius DevOps
e36070cb72
scripts: watcher with correct Forgejo job status codes
1=success 2=failure 3=cancelled 4=skipped 5=waiting 6=running 7=blocked,
terminal is 1..4. The first cut treated 2 as success and reported a failed
job as green.
2026-09-10 13:15:12 -04:00
Sirius DevOps
19af4cc768
ci: build on rust 1.91 — the locked Arti 0.46 crates require rustc >= 1.91
Some checks failed
ci / test (push) Failing after 9m2s
The rust:1.87-bookworm job image failed every builder step with
'tor-*@0.46.0 requires rustc 1.91 ... either upgrade rustc or select
compatible dependency versions'. Cargo.toml declared rust-version 1.87,
which was simply wrong: cargo 1.87 could not even resolve the lockfile.

- rust-version 1.87 -> 1.91 (README requirement text too)
- RUST_IMAGE rust:1.87-bookworm -> rust:1.91-bookworm in ci and release
2026-09-10 13:14:55 -04:00
Sirius DevOps
e7c0b98a2b
ci(release): build the dispatched tag, not the dispatch ref
Some checks failed
ci / test (push) Failing after 21s
Without this a workflow_dispatch re-publish would have built main and
attached a binary whose --version did not match the release tag.
2026-09-10 13:12:39 -04:00
Sirius DevOps
91fd9601b8
ci: Forgejo-native ci + release workflows
Some checks failed
ci / test (push) Failing after 1m6s
The GitHub workflows could never run on this instance: jobs asked for
ubuntu-24.04 runners (the Pi runner only registers the 'docker' label, so
every job sat in waiting), and release.yml published to github.com, which
is not a remote of this repo.

- .forgejo/workflows/ci.yml  — cargo test + clippy on the 'docker' label,
  Rust work in a rust:1.87-bookworm sibling container (aarch64 native)
- .forgejo/workflows/release.yml — on v*.*.* tags, build aarch64, strip,
  sha256, publish to the Forgejo release; workflow_dispatch takes a tag
  to re-publish
- scripts/publish-release.sh — idempotent create-or-update release +
  asset upload via the Forgejo API (replaces same-named assets)
- scripts/build-release-local.sh — x86_64 path (no x86_64 runner exists)
- scripts/release-body.md — release notes template (@TAG@ substituted)
- README: install URLs -> Forgejo, accurate maintainer release procedure
- remove .github/workflows/*
2026-09-10 13:10:56 -04:00
Sirius DevOps
b9f2dc3806
chore: release v0.1.1
Some checks are pending
ci / test (push) Waiting to run
release / x86_64-unknown-linux-gnu (push) Waiting to run
release / aarch64-unknown-linux-gnu (push) Waiting to run
release / publish (push) Blocked by required conditions
Binary --version reports CARGO_PKG_VERSION, so the tag and the crate
version have to move together.
2026-09-10 13:05:02 -04:00
Sirius DevOps
82634db142
tui: ASCII onion chrome, themed panes, and real keyboard navigation
Some checks are pending
ci / test (push) Waiting to run
- Hand-written wordmark banner (<=80 cols, auto-collapses to a compact
  mark below banner width) plus onion glyph and themed screen headings
- Color-palette consts, stateful pane titles, highlighted selection row
  (accent + bg), context-sensitive footer that always keeps '? help'
- Pane focus model (roster/chat/composer) with Tab/Shift-Tab, 1/2/3,
  j/k + arrows, g/G, and a '?' help overlay; Esc closes any overlay
- New tests/tui_chrome.rs: banner widths, help overlay bindings, real
  footer helper at 80 and 120 cols, 80x24 draw smoke test
- README keybinding table updated to match

Locked helper strings (fingerprint_mismatch_banner, rotate_screen_text,
wipe_screen_text, parse_slash) unchanged; UI-only (src/tui.rs).
2026-09-10 13:01:40 -04:00
Sirius DevOps
5c5948c61c
docs: keep release asset filenames so sha256sum -c matches
Some checks are pending
ci / test (push) Waiting to run
2026-09-10 03:05:44 -04:00