Skip to main content

DualLayerHandshake

Struct DualLayerHandshake 

Source
pub struct DualLayerHandshake<Outer, Inner, C, H, const BUF: usize>
where Inner: Handshaker<C, H>, Outer: Handshaker<C, H>, C: Cipher, H: Hash,
{ /* private fields */ }
Expand description

Dual layer handshake

An “outer-encrypts-inner” dual layer handshake with fully independent layers. The outer handshake is completed first, after which the inner handshake starts and all the related handshake messages are encrypted using the outer layers resulting transport encryption.

Warning: this is a naive approach which does NOT cryptographically bind the layers together. Use this handshake type only if you know what you are doing and absolutely require the handshake layers to remain independent.

Dual layer handshakes require an additional intermediate buffer for decrypting outer layer handshake messages. The buffer size is controlled by the generic parameter BUF.

§Message Sequences

With dual layer handshakes it is possible to construct handshake pattern combinations which result in one party having to send two handshake messages in a row. Take care when implementing your handshaking logic and always use Self::is_write_turn to check who should send next.

Implementations§

Source§

impl<Outer, Inner, C, H, const BUF: usize> DualLayerHandshake<Outer, Inner, C, H, BUF>
where Inner: Handshaker<C, H>, Outer: Handshaker<C, H>, C: Cipher, H: Hash,

Source

pub fn new(outer: Outer, inner: Inner) -> Self

Initialize a new dual layer handshake

§Arguments
  • outer - Outer handshake, which is completed first
  • innter - Inner handshake, which benefits from the security of the outer layer
§Generic parameters
  • const BUF - Intermediate decrypt buffer size - Must be large enough to fit all inner handshake messages
§Panics
  • If outer and inner aren’t both either initiators or responders
  • If outer handshake is a one-way pattern
Source

pub fn outer_completed(&self) -> bool

Check if outer handshake is completed

Source

pub fn inner(&self) -> &Inner

Get reference to inner handshake

Source

pub fn inner_mut(&mut self) -> &mut Inner

Get mutable reference to inner handshake

Source

pub fn outer(&self) -> Option<&Outer>

Get reference to outer handshake

Source

pub fn outer_mut(&mut self) -> Option<&mut Outer>

Get mutable reference to outer handshake

Trait Implementations§

Source§

impl<Outer, Inner, C, H, const BUF: usize> Handshaker<C, H> for DualLayerHandshake<Outer, Inner, C, H, BUF>
where Inner: Handshaker<C, H>, Outer: Handshaker<C, H>, C: Cipher, H: Hash,

Source§

fn get_remote_static(&self) -> Option<Self::S>

Get remote static key of the inner handshake (if available)

Source§

fn get_remote_ephemeral(&self) -> Option<Self::E>

Get remote ephemeral key of the inner handshake (if available)

Source§

fn get_state(&self) -> SymmetricState<C, H>

Get a copy of the inner handshakers current SymmetricState

Source§

fn get_state_mut(&mut self) -> &mut SymmetricState<C, H>

Get a mutable reference of the inner handshakers current SymmetricState

Source§

type E = <Inner as Handshaker<C, H>>::E

Ephemeral public key type
Source§

type S = <Inner as Handshaker<C, H>>::S

Static public key type
Source§

fn push_psk(&mut self, _psk: &[u8])

Push a PSK to the PSK queue Read more
Source§

fn is_write_turn(&self) -> bool

Is it our turn to send
Source§

fn is_initiator(&self) -> bool

Are we the initiator
Source§

fn get_next_message_overhead(&self) -> HandshakeResult<usize>

Get next message overhead in bytes
Source§

fn build_name(_: &HandshakePattern) -> ArrayString<128>

Build full name of the protocol with the given pattern
Source§

fn write_message( &mut self, payload: &[u8], out: &mut [u8], ) -> HandshakeResult<usize>

Write next handshake message to the given buffer Read more
Source§

fn read_message( &mut self, message: &[u8], out: &mut [u8], ) -> HandshakeResult<usize>

Read and process next handshake message from given buffer Read more
Source§

fn is_finished(&self) -> bool

Is the handshake finished
Source§

fn get_name(&self) -> ArrayString<128>

Get full name of the selected protocol
Source§

fn finalize(self) -> HandshakeResult<TransportState<C, H>>
where Self: Sized,

Transition into transport mode Read more

Auto Trait Implementations§

§

impl<Outer, Inner, C, H, const BUF: usize> Freeze for DualLayerHandshake<Outer, Inner, C, H, BUF>
where Inner: Freeze, Outer: Freeze, <H as Hash>::Output: Freeze, <C as Cipher>::Key: Freeze,

§

impl<Outer, Inner, C, H, const BUF: usize> RefUnwindSafe for DualLayerHandshake<Outer, Inner, C, H, BUF>
where Inner: RefUnwindSafe, Outer: RefUnwindSafe, <H as Hash>::Output: RefUnwindSafe, <C as Cipher>::Key: RefUnwindSafe,

§

impl<Outer, Inner, C, H, const BUF: usize> Send for DualLayerHandshake<Outer, Inner, C, H, BUF>
where Inner: Send, Outer: Send, <H as Hash>::Output: Send, <C as Cipher>::Key: Send,

§

impl<Outer, Inner, C, H, const BUF: usize> Sync for DualLayerHandshake<Outer, Inner, C, H, BUF>
where Inner: Sync, Outer: Sync, <H as Hash>::Output: Sync, <C as Cipher>::Key: Sync,

§

impl<Outer, Inner, C, H, const BUF: usize> Unpin for DualLayerHandshake<Outer, Inner, C, H, BUF>
where Inner: Unpin, Outer: Unpin, <H as Hash>::Output: Unpin, <C as Cipher>::Key: Unpin,

§

impl<Outer, Inner, C, H, const BUF: usize> UnwindSafe for DualLayerHandshake<Outer, Inner, C, H, BUF>
where Inner: UnwindSafe, Outer: UnwindSafe, <H as Hash>::Output: UnwindSafe, <C as Cipher>::Key: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.