feat: M1 — Noise transport, Cap'n Proto framing, Ping/Pong
Establishes the foundational transport layer for noiseml: - Noise_XX_25519_ChaChaPoly_BLAKE2s handshake (initiator + responder) via `snow`; mutual authentication of static X25519 keys guaranteed before any application data flows. - Length-prefixed frame codec (4-byte LE u32, max 65 535 B per Noise spec) implemented as a Tokio Encoder/Decoder pair. - Cap'n Proto Envelope schema with MsgType enum (Ping, Pong, and future MLS message types defined but not yet dispatched). - Server: TCP listener, one Tokio task per connection, Ping→Pong handler, fresh X25519 keypair logged at startup. - Client: `ping` subcommand — handshake, send Ping, receive Pong, print RTT, exit 0. - Integration tests: bidirectional Ping/Pong with mutual-auth verification; server keypair reuse across sequential connections. - Docker multi-stage build (rust:bookworm → debian:bookworm-slim, non-root) and docker-compose with TCP healthcheck. No MLS group state, no AS/DS, no persistence — out of scope for M1.
This commit is contained in:
52
schemas/envelope.capnp
Normal file
52
schemas/envelope.capnp
Normal file
@@ -0,0 +1,52 @@
|
||||
# envelope.capnp — top-level wire message for all noiseml traffic.
|
||||
#
|
||||
# Every frame exchanged over the Noise channel is serialised as an Envelope.
|
||||
# The Delivery Service routes by (groupId, msgType) without inspecting payload.
|
||||
#
|
||||
# Field sizing rationale:
|
||||
# groupId / senderId : 32 bytes — SHA-256 digest
|
||||
# payload : opaque — MLS blob or control data; size bounded by
|
||||
# the Noise transport max message size (65535 B)
|
||||
# timestampMs : UInt64 — unix epoch milliseconds; sufficient until year 292M
|
||||
#
|
||||
# ID generated with: capnp id
|
||||
@0xe4a7f2c8b1d63509;
|
||||
|
||||
struct Envelope {
|
||||
# Message type discriminant — determines how payload is interpreted.
|
||||
msgType @0 :MsgType;
|
||||
|
||||
# 32-byte SHA-256 digest of the group name.
|
||||
# The Delivery Service uses this as its routing key.
|
||||
# Zero-filled for point-to-point control messages (ping, keyPackageUpload, etc.).
|
||||
groupId @1 :Data;
|
||||
|
||||
# 32-byte SHA-256 digest of the sender's Ed25519 identity public key.
|
||||
senderId @2 :Data;
|
||||
|
||||
# Opaque payload. Interpretation is determined by msgType:
|
||||
# ping / pong — empty
|
||||
# keyPackageUpload — openmls-serialised KeyPackage blob
|
||||
# keyPackageFetch — target identity key (32 bytes)
|
||||
# keyPackageResponse — openmls-serialised KeyPackage blob (or empty if none)
|
||||
# mlsWelcome — MLSMessage blob (Welcome variant)
|
||||
# mlsCommit — MLSMessage blob (PublicMessage / Commit variant)
|
||||
# mlsApplication — MLSMessage blob (PrivateMessage / Application variant)
|
||||
# error — UTF-8 error description
|
||||
payload @3 :Data;
|
||||
|
||||
# Unix timestamp in milliseconds at the time of send.
|
||||
timestampMs @4 :UInt64;
|
||||
|
||||
enum MsgType {
|
||||
ping @0;
|
||||
pong @1;
|
||||
keyPackageUpload @2;
|
||||
keyPackageFetch @3;
|
||||
keyPackageResponse @4;
|
||||
mlsWelcome @5;
|
||||
mlsCommit @6;
|
||||
mlsApplication @7;
|
||||
error @8;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user