1use async_trait::async_trait;
2use rand::{rngs::OsRng, RngCore};
3use serde::{Deserialize, Serialize};
4use thiserror::Error;
5
6use crate::crypto::{KeyExchangeAlgorithm, SessionKeys};
7use crate::messages::{
8 Acknowledge, ControlEnvelope, Keepalive, SessionAck, SessionComplete, SessionEstablished,
9 SessionInit, SessionReady,
10};
11
12pub mod client;
13pub mod keepalive;
14pub mod server;
15pub mod transport;
16
17#[async_trait]
19pub trait HandshakeTransport {
20 async fn send(&mut self, msg: HandshakeMessage) -> Result<(), HandshakeError>;
21 async fn recv(&mut self) -> Result<HandshakeMessage, HandshakeError>;
22}
23
24#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
26pub enum HandshakeMessage {
27 SessionInit(SessionInit),
28 SessionAck(SessionAck),
29 SessionReady(SessionReady),
30 SessionComplete(SessionComplete),
31 SessionEstablished(SessionEstablished),
32 Keepalive(Keepalive),
33 Control(ControlEnvelope),
34 Ack(Acknowledge),
35}
36
37#[derive(Debug, Clone)]
39pub struct HandshakeContext {
40 pub key_algorithm: KeyExchangeAlgorithm,
41 pub expected_controller: Option<String>,
42 pub required_firmware_rev: Option<String>,
43}
44
45impl Default for HandshakeContext {
46 fn default() -> Self {
47 Self {
48 key_algorithm: KeyExchangeAlgorithm::X25519,
49 expected_controller: None,
50 required_firmware_rev: None,
51 }
52 }
53}
54
55#[derive(Debug, Error)]
56pub enum HandshakeError {
57 #[error("transport error: {0}")]
58 Transport(String),
59 #[error("protocol violation: {0}")]
60 Protocol(String),
61 #[error("authentication failed: {0}")]
62 Authentication(String),
63 #[error("unsupported capability: {0}")]
64 Capability(String),
65}
66
67pub fn new_nonce() -> [u8; 32] {
69 let mut bytes = [0u8; 32];
70 OsRng.fill_bytes(&mut bytes);
71 bytes
72}
73
74#[async_trait]
76pub trait HandshakeParticipant {
77 async fn run<T: HandshakeTransport + Send>(
78 &self,
79 transport: &mut T,
80 ) -> Result<HandshakeOutcome, HandshakeError>;
81}
82
83pub trait ChallengeAuthenticator {
85 fn sign_challenge(&self, nonce: &[u8]) -> Vec<u8>;
86 fn verify_challenge(&self, nonce: &[u8], signature: &[u8]) -> bool;
87}
88
89#[derive(Debug, Clone)]
91pub struct HandshakeOutcome {
92 pub established: SessionEstablished,
93 pub keys: SessionKeys,
94}