pub struct SignedRoomMessage {
pub fingerprint: String,
pub ed25519_pubkey_b64: String,
pub payload_b64: String,
pub signature_b64: String,
pub signed_at_ms: i64,
}Expand description
Application-level signed envelope around a RoomMessage. Used for
any message whose authenticity matters beyond gossipsub’s transport-
level signing.
The following variants MUST be sent inside a Signed envelope, and
receivers MUST drop them when they arrive unsigned:
MemberLeave(signer must equal the claimedsender_fingerprint; huddle 0.7.11 — closes the unsigned-leave spoof bug)MemberAnnounce(signer must equal the claimedsender_fingerprint; huddle 0.7.11 — closes the TOFU-pubkey hijack bug)FileOffer(signer must equal the claimedsender_fingerprint; huddle 0.7.11 — prevents attribution spoofing)RotateRoomKey(signer must equal the claimedrotator_fingerprint)OwnerGrant,BanMember(signer must be a current room owner)SasInit,SasResponse,SasConfirm(SAS handshake — signature binds the ephemeral X25519 pubkey to the sender’s identity)CodeJoinRequest,CodeJoinResponse(signer is the joiner / owner)JoinRefused(signer is a room owner; tells the rejected joiner it really came from the room)ProfileUpdate(signer must equal the claimedsender_fingerprint; prevents anyone from spoofing another peer’s username)
Verification happens via crate::crypto::verify_signed: it re-derives
the fingerprint from ed25519_pubkey_b64, asserts equality with
fingerprint, runs Ed25519::verify_strict over the decoded
payload_b64, and rejects envelopes whose signed_at_ms falls
outside a ±5 min window from now (replay protection).
Format choice: payload is base64’d serialized RoomMessage JSON
(not the JSON bytes directly) so the envelope itself is plain JSON
without escaping nightmares.
Fields§
§fingerprint: String§ed25519_pubkey_b64: String§payload_b64: String§signature_b64: String§signed_at_ms: i64huddle 0.7.11: epoch-ms timestamp the sender bound into the
signature, used by receivers as replay protection. #[serde(default)]
for forward-compat parsing — but the verifier rejects 0 and
values outside the configured window, so legacy pre-0.7.11 senders
no longer satisfy verify_signed.
Trait Implementations§
Source§impl Clone for SignedRoomMessage
impl Clone for SignedRoomMessage
Source§fn clone(&self) -> SignedRoomMessage
fn clone(&self) -> SignedRoomMessage
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for SignedRoomMessage
impl Debug for SignedRoomMessage
Source§impl<'de> Deserialize<'de> for SignedRoomMessage
impl<'de> Deserialize<'de> for SignedRoomMessage
Source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
Source§impl PartialEq for SignedRoomMessage
impl PartialEq for SignedRoomMessage
Source§fn eq(&self, other: &SignedRoomMessage) -> bool
fn eq(&self, other: &SignedRoomMessage) -> bool
self and other values to be equal, and is used by ==.Source§impl Serialize for SignedRoomMessage
impl Serialize for SignedRoomMessage
impl Eq for SignedRoomMessage
impl StructuralPartialEq for SignedRoomMessage
Auto Trait Implementations§
impl Freeze for SignedRoomMessage
impl RefUnwindSafe for SignedRoomMessage
impl Send for SignedRoomMessage
impl Sync for SignedRoomMessage
impl Unpin for SignedRoomMessage
impl UnsafeUnpin for SignedRoomMessage
impl UnwindSafe for SignedRoomMessage
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more