Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 


Quelle  handshake.rs   Sprache: unbekannt

 
Spracherkennung für: .rs vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

//! Payloads exchanged during the handshake phase.
use educe::Educe;
use libthreema_macros::Name;
use prost::Message as _;

use crate::{
    common::keys::PublicKey,
    d2m::{
        D2mProtocolError,
        payload::{PayloadDecoder, PayloadEncoder},
    },
    protobuf::d2m as protobuf,
    utils::{
        bytes::{ByteWriter, OwnedVecByteReader},
        debug::{Name, debug_slice_length},
        time::{ClockDelta, Duration},
    },
};

/// Decoder for a specific D2M payload.
trait SpecificPayloadDecoder: Sized + Name {
    const TYPE: u8;

    fn decode(reader: OwnedVecByteReader) -> Result<Self, D2mProtocolError>;
}
impl<TDecoder: SpecificPayloadDecoder> PayloadDecoder for TDecoder {
    fn decode(r#type: u8, reader: OwnedVecByteReader) -> Result<Self, D2mProtocolError> {
        // Ensure the type matches the one we expect
        if r#type != Self::TYPE {
            return Err(D2mProtocolError::UnexpectedPayloadType(r#type));
        }

        // Decode payload
        Self::decode(reader)
    }
}

#[repr(u8)]
enum HandshakePayloadType {
    ServerHello = 0x10,
    ClientHello = 0x11,
    ServerInfo = 0x12,
}

/// Initial message from the server, containing an authentication challenge.
#[derive(Name, Educe)]
#[educe(Debug)]
pub(crate) struct ServerHello {
    /// Highest protocol version [`protobuf::ProtocolVersion`] the server supports.
    pub(crate) version: u32,

    /// Ephemeral Server Key (ESK).
    pub(crate) ephemeral_server_key: PublicKey,

    /// 32 byte random challenge
    #[educe(Debug(method(debug_slice_length)))]
    pub(crate) challenge: [u8; 32],
}
impl SpecificPayloadDecoder for ServerHello {
    const TYPE: u8 = HandshakePayloadType::ServerHello as u8;

    fn decode(reader: OwnedVecByteReader) -> Result<Self, D2mProtocolError> {
        let protobuf::ServerHello {
            version,
            esk,
            challenge,
        } = Self::decode_protobuf(reader)?;
        Ok(Self {
            version,
            ephemeral_server_key: PublicKey::try_from(esk.as_slice()).map_err(|_| {
                D2mProtocolError::InvalidMessage {
                    name: Self::NAME,
                    cause: "Invalid ephemeral server key".to_owned(),
                }
            })?,
            challenge: challenge
                .try_into()
                .map_err(|_| D2mProtocolError::InvalidMessage {
                    name: Self::NAME,
                    cause: "Invalid challenge length".to_owned(),
                })?,
        })
    }
}

/// Initial message from the client, containing the authentication challenge response and additional login
/// information.
impl PayloadEncoder for protobuf::ClientHello {
    #[inline]
    fn type_and_length(&self) -> (u8, Option<usize>) {
        (HandshakePayloadType::ClientHello as u8, Some(self.encoded_len()))
    }

    #[inline]
    fn encode_into<TWriter: ByteWriter>(self, writer: &mut TWriter) -> Result<(), D2mProtocolError> {
        Self::encode_protobuf(self, writer)
    }
}

/// Parts of the server's configuration and the device slot state.
#[derive(Name, Educe)]
#[educe(Debug)]
pub struct ServerInfo {
    /// 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,

    /// Maximum number of available device slots.
    pub max_device_slots: u32,

    /// Device slot state of the client on the server.
    pub device_slot_state: Option<protobuf::DeviceSlotState>,

    /// Device data shared among devices (`SharedDeviceData`), encrypted by `DGSDDK.secret` and prefixed with
    /// a random nonce.
    #[educe(Debug(method(debug_slice_length)))]
    pub encrypted_shared_device_data: Vec<u8>,

    /// Amount of messages in the reflection queue that will now be sent to the device. If the client is
    /// up-to-date, the value will be 0.
    ///
    /// Note: The amount of messages in the reflection queue may increase at any time, so there is no
    /// guarantee that `ReflectionQueueDry` will be received after having received `reflection_queue_length`
    /// reflected messages.
    pub reflection_queue_length: u32,
}
impl SpecificPayloadDecoder for ServerInfo {
    const TYPE: u8 = HandshakePayloadType::ServerInfo as u8;

    fn decode(reader: OwnedVecByteReader) -> Result<Self, D2mProtocolError> {
        let protobuf::ServerInfo {
            current_time,
            max_device_slots,
            device_slot_state,
            encrypted_shared_device_data,
            reflection_queue_length,
        } = Self::decode_protobuf(reader)?;
        Ok(Self {
            clock_delta: ClockDelta::calculate(Duration::from_millis(current_time)),
            max_device_slots,
            device_slot_state: protobuf::DeviceSlotState::try_from(device_slot_state).ok(),
            encrypted_shared_device_data,
            reflection_queue_length,
        })
    }
}

[Dauer der Verarbeitung: 0.18 Sekunden, vorverarbeitet 2026-04-27]

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Produkte
     Quellcodebibliothek

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Monitoring

Montastic status badge