pub struct PassiveHandshake { /* private fields */ }Expand description
Provides the passive part of the handshake.
The passive part of the handshake only really responds to the stuff the active part tells it. This includes the enabled features, which cannot be configured here but will be part of the setup sent from the active part. We’re currently expecting the other side to initialize a handshake, but this is technically not required. How you deal with that is up to you.
An example exchange could look like this:
let mut passive = PassiveHandshake::default();
// The active side will create an initialization, which will be sent to the passive side.
// We simply plug that information into our procedure. For now, we assume they're setting up
// encryption as well, so we simply `unwrap()` everything here.
let (value_key, value_b) = passive.initialize(init.encryption_seed).unwrap().unwrap();
// These two values should then be sent to the active side again. That side will then respond
// with a challenge for us, to verify everything went fine.
passive.finish(challenge).unwrap();
// We then need to complete the handshake, which we should signal to the active part as well.
// `finish` and `done` are separate things, because if the active part does not actually send
// encryption information we can't call `finish`. We'd instead just call `done`.
let encryption = passive.done().expect("Handshake should have completed.");Implementations§
Source§impl PassiveHandshake
impl PassiveHandshake
Sourcepub fn initialize(
&mut self,
init: Option<PassiveEncryptionInitializationData>,
) -> Result<Option<(u64, u32)>, SilkroadSecurityError>
pub fn initialize( &mut self, init: Option<PassiveEncryptionInitializationData>, ) -> Result<Option<(u64, u32)>, SilkroadSecurityError>
Initialize the handshake with the data from the active side.
We have received the initialization data from the active handshake side and want to
initialize our side as well. Depending on the security features selected by the active side,
the initialization data may actually be None, which is why this accepts and Option.
Technically, if you haven’t received any encryption initialization data, you can simply call
PassiveHandshake::done and complete the handshake - there’s nothing more to be exchanged.
This is essentially a convenience to stay more consistent with what we receive from the
active part.
This may error if we’re already initialized, returning SilkroadSecurityError::InitializationUnfinished.
Sourcepub fn finish(&mut self, challenge: u64) -> Result<(), SilkroadSecurityError>
pub fn finish(&mut self, challenge: u64) -> Result<(), SilkroadSecurityError>
Complete the handshake by verifying the challenge.
After we have sent our initialization data to the active part, they provide us with a sort of challenge. If we can verify the challenge with what we internally calculated, we know the key exchange was successful, and we now have a shared secret. At this point, the handshake is essentially completed. This should be signaled to the active side by switching to an encrypted channel.
Sourcepub fn done(self) -> Result<Option<SilkroadEncryption>, SilkroadSecurityError>
pub fn done(self) -> Result<Option<SilkroadEncryption>, SilkroadSecurityError>
Return the resulting encryption from the handshake.
If the selected security features of the active handshake part included setting up the
encryption, the final result will be returned. If it didn’t contain that feature, it will
return None instead.
Will return SilkroadSecurityError::InitializationUnfinished if we haven’t completed the handshake yet.