/// Initial payload from the client, containing a server authentication challenge in order to /// establish transport layer encryption. #[derive(Debug, Name)] pub(crate) struct ClientHello { pub(crate) temporary_client_key_public: PublicKey, pub(crate) client_cookie: ClientCookie,
} impl ClientHello { const LENGTH: usize = PublicKey::LENGTH + Cookie::LENGTH;
} impl FrameEncoder for ClientHello { fn encode_frame(&self) -> Result<OutgoingFrame, CspProtocolError> { let encoded: [u8; Self::LENGTH] = concat_fixed_bytes!(
*self.temporary_client_key_public.0.as_bytes(), self.client_cookie.0.0
);
Ok(OutgoingFrame(encoded.to_vec()))
}
}
/// Initial payload from the server. /// /// This concludes establishing transport layer encryption based on temporary client and server key. #[derive(Debug)] pub(crate) struct ServerHello { pub(crate) server_cookie: ServerCookie,
let server_cookie = ServerCookie(Cookie(
reader
.read_fixed::<{ Cookie::LENGTH }>()
.expect("data must be >= Cookie::LENGTH"),
));
let server_challenge_response_box = reader
.read_fixed::<{ Self::SERVER_CHALLENGE_RESPONSE_BOX_LENGTH }>()
.expect("data must be >= Cookie::LENGTH + SERVER_CHALLENGE_BOX_RESPONSE_LENGTH");
/// A collection of extensions. #[derive(Name)] pub(crate) struct Extensions(Vec<Extension>); impl Extensions { const ENCRYPTION_OVERHEAD_LENGTH: usize = salsa20::TAG_LENGTH;
/// Create a set of extensions of all necessary extensions from the provided context. pub(crate) fn new(context: &CspProtocolContext) -> Self { // Set the supported features and client info letmut extensions = vec![
Extension::SupportedFeatures(Features(
Features::SUPPORTS_MESSAGE_WITH_METADATA_BOX | Features::SUPPORTS_RECEIVING_ECHO_REQUEST,
)),
Extension::ClientInfo(context.client_info.clone()),
];
// Add CSP device ID, if any
extensions.extend(context.csp_device_id.map(Extension::CspDeviceId));
// Add device cookie, if any
extensions.extend(context.device_cookie.map(Extension::DeviceCookie));
Self(extensions)
}
/// Encode all extensions and return them alongside the extension length **with encryption /// overhead** needed for [`LoginData`]. pub(crate) fn encode(&self) -> Result<(Vec<u8>, u16), CspProtocolError> { // Encode all extensions, one after another letmut writer = OwnedVecByteWriter::new_empty(); for extension in &self.0 {
extension.encode_into(&mut writer)?;
} let encoded = writer.into_inner(); let length_with_overhead: u16 = encoded
.len()
.checked_add(Self::ENCRYPTION_OVERHEAD_LENGTH)
.ok_or(InternalErrorCause::from( "Encoded extensions length exceeded a u16",
))?
.try_into()
.map_err(|_| InternalErrorCause::from("Encoded extensions length exceeded a u16"))?;
Ok((encoded, length_with_overhead))
}
}
/// Login data of the client. #[derive(Educe, Name)] #[educe(Debug)] pub(crate) struct LoginData { pub(crate) identity: ThreemaId,
/// Byte length of the **encrypted** extensions (meaning with overhead, provided separately /// within [`Login`]) pub(crate) extensions_byte_length: u16,
/// Repeated server connection Cookie (SCK), acting as the client's challenge response pub(crate) repeated_server_cookie: ServerCookie,
/// Login acknowledgement data from the server. #[derive(Debug, Name)] pubstruct LoginAckData { /// Clock delta between the server's time and the client's time. /// /// If the client's current timestamp deviates by more than 20 minutes, the client should disconnect and /// prompt the user to synchronise its clock. The user should also have an option to _connect anyway_ /// which should be cached for a reasonable amount of time. pub clock_delta: ClockDelta,
/// Amount of queued messages on the server for the client. /// /// Note: The amount of messages in the reflection queue may increase at any time, so there is no /// guarantee that `QueueSendComplete` will be received after having received `queued_messages` messages. pub queued_messages: u32,
} impl LoginAckData { const LENGTH: usize = Self::RESERVED_LENGTH + 8 + 4; const RESERVED_LENGTH: usize = 4;
} impl TryFrom<&[u8]> for LoginAckData { type Error = CspProtocolError;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.