Skip to main content

ap_proxy_protocol/
messages.rs

1//! Protocol message types for client-proxy communication.
2//!
3//! This module defines the message types used in the three-phase protocol:
4//!
5//! # Message Flow
6//!
7//! ## Phase 1: Authentication
8//! 1. Server → Client: [`Messages::AuthChallenge`] - Random challenge for the client to sign
9//! 2. Client → Server: [`Messages::AuthResponse`] - Client's identity and signature
10//!
11//! ## Phase 2: Rendezvous (Optional)
12//! 3. Client → Server: [`Messages::GetRendezvous`] - Request a temporary code
13//! 4. Server → Client: [`Messages::RendezvousInfo`] - The generated code (e.g., "ABC-DEF-GHI")
14//! 5. Client → Server: [`Messages::GetIdentity`] - Look up identity by code
15//! 6. Server → Client: [`Messages::IdentityInfo`] - The identity associated with the code
16//!
17//! ## Phase 3: Messaging
18//! 7. Client → Server: [`Messages::Send`] - Client sends message (destination + payload only)
19//! 8. Server → Client: [`Messages::Send`] - Server forwards with validated source added
20//!
21//! All messages are serialized as JSON over WebSocket connections.
22
23use crate::{
24    auth::{Challenge, ChallengeResponse, Identity, IdentityFingerprint},
25    rendezvous::RendezvousCode,
26};
27use serde::{Deserialize, Serialize};
28
29/// Protocol messages exchanged between clients and the proxy server.
30///
31/// Messages flow through three distinct phases: authentication, optional rendezvous
32/// for peer discovery, and message routing between authenticated clients.
33#[derive(Debug, Clone, Serialize, Deserialize)]
34pub enum Messages {
35    /// Server sends a random challenge to a newly connected client.
36    ///
37    /// The client must sign this challenge with its private key to authenticate.
38    /// Sent immediately after WebSocket connection establishment.
39    AuthChallenge(Challenge),
40
41    /// Client responds to authentication challenge with identity and signature.
42    ///
43    /// Contains the client's public [`Identity`] and a [`ChallengeResponse`] (signature).
44    /// The server verifies the signature to authenticate the client.
45    AuthResponse(Identity, ChallengeResponse),
46
47    /// Client requests a temporary rendezvous code.
48    ///
49    /// The server will generate a unique code (format: "ABC-DEF-GHI") and send it back
50    /// via [`Messages::RendezvousInfo`]. The code expires after 5 minutes.
51    GetRendezvous,
52
53    /// Server responds with the generated rendezvous code.
54    ///
55    /// The code can be shared with other clients to enable them to discover
56    /// this client's identity via [`Messages::GetIdentity`].
57    RendezvousInfo(RendezvousCode),
58
59    /// Client looks up an identity using a rendezvous code.
60    ///
61    /// If the code is valid and hasn't expired, the server responds with
62    /// [`Messages::IdentityInfo`]. Codes are single-use and deleted after lookup.
63    GetIdentity(RendezvousCode),
64
65    /// Server responds with the identity associated with a rendezvous code.
66    ///
67    /// Contains both the [`IdentityFingerprint`] (SHA256 hash) and full [`Identity`]
68    /// (public key). After sending this, the rendezvous code is deleted.
69    IdentityInfo {
70        /// SHA256 fingerprint of the identity's public key
71        fingerprint: IdentityFingerprint,
72        /// The full public identity (MlDsa65 public key)
73        identity: Identity,
74    },
75
76    /// A message routed from one client to another through the proxy.
77    ///
78    /// When sent by clients, only contains destination and payload. The source is
79    /// automatically set by the proxy based on the authenticated identity.
80    /// When forwarded to recipients, includes the validated source fingerprint.
81    Send {
82        /// The authenticated sender's fingerprint (added by proxy)
83        #[serde(skip_serializing_if = "Option::is_none")]
84        source: Option<IdentityFingerprint>,
85        /// The recipient's fingerprint
86        destination: IdentityFingerprint,
87        /// Arbitrary payload data (should be encrypted by clients)
88        payload: Vec<u8>,
89    },
90}