Files
securebit-chat/doc/API.md
T
lockbitchat 27279ae7c6
CodeQL Analysis / Analyze CodeQL (push) Waiting to run
Deploy Application / deploy (push) Waiting to run
Mirror to Codeberg / mirror (push) Waiting to run
Mirror to PrivacyGuides / mirror (push) Waiting to run
feat(crypto): Double Ratchet forward secrecy; hardening pass; release v5.7.1
Adds the Double Ratchet (Signal's design) on top of the existing ECDH session
keys, so message protection no longer rests on one set of keys lasting the whole
conversation. Every message gets its own key, derived through a one-way function
and discarded after use, and each change of direction introduces a fresh ECDH
key pair that re-keys the session root.

The ratchet needed no handshake change: both peers already hold each other's
authenticated ECDH public key, and the safety code compared during verification
covers exactly those keys. Its root is derived from the existing shared secret
through its own branch of the key schedule.

Support is negotiated in the invitation and response and used only when both
sides have it; a peer on an earlier release falls back to per-session keys. The
security panel reports which of the two is actually in force.

Out-of-order delivery is supported within fixed bounds (512 skipped keys per
chain, 1024 retained, five-minute expiry), and inbound frames are authenticated
before any ratchet state is committed, so a malformed frame cannot desynchronise
a live session.

Also in this release:

- Verification is enforced as a gate, not a label: control frames (reconnection
  signalling, call setup, message deletion, delivery receipts) are acted on only
  after both peers have compared the safety code, and verified state is set in a
  single guarded place.
- Chat content reaches the interface through one authenticated path; an older,
  weaker inbound path was retired.
- The security panel measures what it displays — several checks previously
  returned a fixed result and now exercise the subsystem they describe.
- Invitation data is no longer kept in local storage, and entries left by earlier
  versions are cleared on first launch.
- View-once and disappearing messages no longer place their text in system
  notifications.
- Shared-secret buffers are overwritten once derivation completes; scanned QR
  codes are decompressed with a size limit; voice notes are validated against
  audio type and size budgets before skipping the consent prompt; the master
  password is collected by the app rather than a browser dialog.
- Connection setup no longer fails on networks where STUN/TURN are unreachable:
  it proceeds as soon as usable candidates exist and only waits while there are
  none.

Test suite grows from 27 to 41 files, covering forward secrecy, post-compromise
re-keying, out-of-order delivery across ratchet steps, the skipped-key bounds,
tamper resistance, negotiation fallback, and byte-level key-derivation
compatibility with 5.6.0.
2026-08-05 23:02:20 -04:00

79 lines
3.5 KiB
Markdown

# API Notes
## EnhancedSecureWebRTCManager
### Verification
- `confirmVerification(userCode)` validates a manually entered SAS code.
- Verification succeeds only after both local and remote confirmations are present.
- `isVerified` is assigned in one place (`_setVerifiedStatus`), which refuses any
SAS-based transition without a recorded local confirmation.
- Control frames listed in `POST_VERIFICATION_CONTROL_TYPES` (reconnection
signalling, call setup, message deletion, delivery receipts) are only acted on
after verification. The set is an allowlist; unrecognised frame types are
rejected by the chat channel's default-deny branch.
- Protocol version `4.1` is enforced during offer/answer processing.
### Forward secrecy
- `isRatchetActive()` reports whether the Double Ratchet is running on this
connection. It is negotiated: both peers advertise `RATCHET_VERSION` in the
offer and answer, and a peer that does not falls back to per-session keys.
- `_ratchet.canEncrypt` is false on the joining peer until the inviting peer's
first message arrives — the sending chain does not exist until then. Callers
must check it rather than assume; the send path falls back to session keys for
those first frames.
- `_ratchet.getState()` returns counters and the number of retained keys for
diagnostics. It exposes no key material.
- Ratcheted chat arrives as `MESSAGE_TYPES.RATCHET_MESSAGE` with `h` (the header
string, used verbatim as AES-GCM additional data) and `c` (base64 body). The
header must be passed back to `decrypt()` exactly as received; re-serialising
it can change a byte and fail authentication.
### Privacy mode
- relay-only configuration sets WebRTC `iceTransportPolicy` to `"relay"`.
- TURN availability is checked before claiming IP protection.
### File transfer callbacks
- `setFileTransferCallbacks(onProgress, onReceived, onError, onIncomingRequest)` updates manager fields and any live `EnhancedSecureFileTransfer` instance.
- Passing `null` values detaches callbacks from the active transfer system.
### Voice messages
- `sendFile(file, options)` accepts an optional `options` object. `options.voice`
(`{ dur, bars }`) marks the transfer as a voice note and rides along as unsigned
metadata; `options.uiId` correlates progress events to a UI bubble before the
`fileId` resolves.
- `onProgress` receives `{ fileId, uiId, direction, progress, isVoice, voice }`.
`onIncomingFileRequest` and `onReceived` include `isVoice` and `voice` so the UI
can auto-accept and render a voice bubble instead of a file card.
- The `isVoice` a callback receives is the **receiver's** verdict, not the
sender's claim: `validateIncomingMetadata` clears it unless the transfer
declares a recognised audio MIME type and fits the per-note and per-session
size budgets. A transfer that fails those checks is not rejected — it simply
loses the consent-free shortcut and is offered as a normal file.
## EnhancedSecureFileTransfer
### Incoming transfers
- metadata is validated before prompting
- acceptance is explicit
- receive buffers are allocated only after consent
- file type acceptance is allowlist-based
### Cleanup
- pending sender consent promises are rejected on cleanup
- consent timeouts are cleared immediately
- retained received buffers are bounded
- evicted download handles fail with a user-facing availability message
## SecurePersistentKeyStorage
- metadata is encrypted before storage
- legacy plaintext records migrate lazily
- corrupted encrypted metadata is ignored safely