added a more flexible trait to handle sending

This commit is contained in:
Monica Moniot
2023-09-29 10:08:05 -04:00
parent 185f137ec3
commit f0c7ea571c
6 changed files with 136 additions and 79 deletions
+15 -16
View File
@@ -16,7 +16,6 @@ use zssp::application::{
use zssp::crypto::P384KeyPair;
use zssp::crypto_impl::*;
use zssp::result::ReceiveError;
use zssp::Session;
const TEST_MTU: usize = 1500;
@@ -26,6 +25,8 @@ struct TestApplication {
ratchets: Mutex<Ratchets>,
}
type Session = zssp::Session<TestApplication>;
struct Ratchets {
rf_map: HashMap<[u8; RATCHET_SIZE], RatchetState>,
peer_map: HashMap<u128, RatchetStates>,
@@ -64,9 +65,7 @@ impl CryptoLayer for TestApplication {
type IncomingPacketBuffer = Vec<u8>;
}
#[allow(unused)]
impl ApplicationLayer for &TestApplication {
type Crypto = TestApplication;
impl ApplicationLayer<TestApplication> for &TestApplication {
fn incoming_session(&mut self) -> IncomingSessionAction {
IncomingSessionAction::Challenge
}
@@ -75,7 +74,7 @@ impl ApplicationLayer for &TestApplication {
false
}
fn initiator_disallows_downgrade(&mut self, session: &Arc<Session<TestApplication>>) -> bool {
fn initiator_disallows_downgrade(&mut self, session: &Arc<Session>) -> bool {
true
}
@@ -162,7 +161,7 @@ fn alice_main(
up = false;
let result = context.open(
alice_app,
|b| alice_out.send(b.to_vec()).is_ok(),
|b: &mut [u8]| alice_out.send(b.to_vec()).is_ok(),
TEST_MTU,
bob_pubkey.clone(),
0,
@@ -181,9 +180,9 @@ fn alice_main(
let mut output_data = Vec::new();
match context.receive(
alice_app,
|b| alice_out.send(b.to_vec()).is_ok(),
|b: &mut [u8]| alice_out.send(b.to_vec()).is_ok(),
TEST_MTU,
|_| Some((|b: &mut [u8]| alice_out.send(b.to_vec()).is_ok(), TEST_MTU)),
|_: &Arc<Session>| Some((|b: &mut [u8]| alice_out.send(b.to_vec()).is_ok(), TEST_MTU)),
&0,
pkt,
&mut output_data,
@@ -191,7 +190,7 @@ fn alice_main(
Ok((Unassociated, _)) => {
//println!("[alice] ok");
}
Ok((Session(_, event), _)) => match event {
Ok((SessionEvent(_, event), _)) => match event {
Established => {
up = true;
}
@@ -221,7 +220,7 @@ fn alice_main(
context
.send(
alice_session.as_ref().unwrap(),
|b| alice_out.send(b.to_vec()).is_ok(),
|b: &mut [u8]| alice_out.send(b.to_vec()).is_ok(),
&mut [0u8; TEST_MTU],
&test_data[..1400 + ((OsRng.next_u64() as usize) % (test_data.len() - 1400))],
)
@@ -236,7 +235,7 @@ fn alice_main(
if current_time >= next_service {
next_service = current_time
+ context.service(alice_app, |_| {
+ context.service(alice_app, |_: &Arc<Session>| {
Some((|b: &mut [u8]| alice_out.send(b.to_vec()).is_ok(), TEST_MTU))
});
}
@@ -272,15 +271,15 @@ fn bob_main(
let mut output_data = Vec::new();
match context.receive(
bob_app,
|b| bob_out.send(b.to_vec()).is_ok(),
|b: &mut [u8]| bob_out.send(b.to_vec()).is_ok(),
TEST_MTU,
|_| Some((|b: &mut [u8]| bob_out.send(b.to_vec()).is_ok(), TEST_MTU)),
|_: &Arc<Session>| Some((|b: &mut [u8]| bob_out.send(b.to_vec()).is_ok(), TEST_MTU)),
&0,
pkt,
&mut output_data,
) {
Ok((Unassociated, _)) => {}
Ok((Session(s, event), _)) => match event {
Ok((SessionEvent(s, event), _)) => match event {
NewSession | NewDowngradedSession => {
println!("[bob] new session, took {}s", current_time as f32 / 1000.0);
let _ = bob_session.replace(s);
@@ -292,7 +291,7 @@ fn bob_main(
context
.send(
&s,
|b| bob_out.send(b.to_vec()).is_ok(),
|b: &mut [u8]| bob_out.send(b.to_vec()).is_ok(),
&mut [0u8; TEST_MTU],
&output_data,
)
@@ -325,7 +324,7 @@ fn bob_main(
if current_time >= next_service {
next_service = current_time
+ context.service(bob_app, |_| {
+ context.service(bob_app, |_: &Arc<Session>| {
Some((|b: &mut [u8]| bob_out.send(b.to_vec()).is_ok(), TEST_MTU))
});
}
+17 -16
View File
@@ -13,7 +13,6 @@ use zssp::application::{
use zssp::crypto::P384KeyPair;
use zssp::crypto_impl::*;
use zssp::result::ReceiveError;
use zssp::Session;
const TEST_MTU: usize = 1500;
@@ -56,10 +55,11 @@ impl DefaultCrypto for TestApplication {
type SessionData = ();
type IncomingPacketBuffer = PooledVec;
}
#[allow(unused)]
impl ApplicationLayer for &TestApplication {
type Crypto = TestApplication;
type Session = zssp::Session<TestApplication>;
#[allow(unused)]
impl ApplicationLayer<TestApplication> for &TestApplication {
fn incoming_session(&mut self) -> IncomingSessionAction {
IncomingSessionAction::Allow
}
@@ -68,7 +68,7 @@ impl ApplicationLayer for &TestApplication {
false
}
fn initiator_disallows_downgrade(&mut self, session: &Arc<Session<TestApplication>>) -> bool {
fn initiator_disallows_downgrade(&mut self, session: &Arc<Session>) -> bool {
false
}
@@ -113,6 +113,7 @@ impl ApplicationLayer for &TestApplication {
}
}
#[allow(unused)]
fn alice_main(
run: &AtomicBool,
@@ -131,7 +132,7 @@ fn alice_main(
let result = context.open(
alice_app,
|b| alice_out.send(alloc(b)).is_ok(),
|b: &mut [u8]| alice_out.send(alloc(b)).is_ok(),
TEST_MTU,
bob_pubkey.clone(),
(),
@@ -149,9 +150,9 @@ fn alice_main(
output_data.clear();
match context.receive(
alice_app,
|b| alice_out.send(alloc(b)).is_ok(),
|b: &mut [u8]| alice_out.send(alloc(b)).is_ok(),
TEST_MTU,
|_| Some((|b: &mut [u8]| alice_out.send(alloc(b)).is_ok(), TEST_MTU)),
|_: &Arc<zssp::Session<TestApplication>>| Some((|b: &mut [u8]| alice_out.send(alloc(b)).is_ok(), TEST_MTU)),
&0,
pkt,
&mut output_data,
@@ -159,7 +160,7 @@ fn alice_main(
Ok((Unassociated, _)) => {
//println!("[alice] ok");
}
Ok((Session(_, event), _)) => match event {
Ok((SessionEvent(_, event), _)) => match event {
Established => {
up = true;
}
@@ -186,7 +187,7 @@ fn alice_main(
context
.send(
alice_session.as_ref().unwrap(),
|b| alice_out.send(alloc(b)).is_ok(),
|b: &mut [u8]| alice_out.send(alloc(b)).is_ok(),
&mut [0u8; TEST_MTU],
&test_data[..1400 + ((OsRng.next_u64() as usize) % (test_data.len() - 1400))],
)
@@ -197,7 +198,7 @@ fn alice_main(
if current_time >= next_service {
next_service = current_time
+ context.service(alice_app, |_| {
+ context.service(alice_app, |_: &Arc<Session>| {
Some((|b: &mut [u8]| alice_out.send(alloc(b)).is_ok(), TEST_MTU))
});
}
@@ -231,15 +232,15 @@ fn bob_main(
output_data.clear();
match context.receive(
bob_app,
|b| bob_out.send(alloc(b)).is_ok(),
|b: &mut [u8]| bob_out.send(alloc(b)).is_ok(),
TEST_MTU,
|_| Some((|b: &mut [u8]| bob_out.send(alloc(b)).is_ok(), TEST_MTU)),
|_: &Arc<Session>| Some((|b: &mut [u8]| bob_out.send(alloc(b)).is_ok(), TEST_MTU)),
&0,
pkt,
&mut output_data,
) {
Ok((Unassociated, _)) => {}
Ok((Session(s, event), _)) => match event {
Ok((SessionEvent(s, event), _)) => match event {
NewSession | NewDowngradedSession => {
println!("[bob] new session, took {}s", current_time as f32 / 1000.0);
let _ = bob_session.replace(s);
@@ -251,7 +252,7 @@ fn bob_main(
context
.send(
&s,
|b| bob_out.send(alloc(b)).is_ok(),
|b: &mut [u8]| bob_out.send(alloc(b)).is_ok(),
&mut [0u8; TEST_MTU],
&output_data,
)
@@ -281,7 +282,7 @@ fn bob_main(
if current_time >= next_service {
next_service = current_time
+ context.service(bob_app, |_| {
+ context.service(bob_app, |_: &Arc<Session>| {
Some((|b: &mut [u8]| bob_out.send(alloc(b)).is_ok(), TEST_MTU))
});
}
+69 -12
View File
@@ -142,16 +142,20 @@ pub trait CryptoLayer: Sized {
type IncomingPacketBuffer: AsRef<[u8]> + AsMut<[u8]>;
}
pub trait ApplicationLayer: Sized {
/// Specifies which concrete set of cryptography types will be used by this application.
type Crypto: CryptoLayer;
pub trait ApplicationLayer<Crypto: CryptoLayer>: Sized {
/// Should return the current time in milliseconds. Does not have to be monotonic, nor synced
/// with remote peers (although both of these properties would help reliability slightly).
/// Used to determine if any current handshakes should be resent or timed-out, or if a session
/// should rekey.
fn time(&mut self) -> i64;
/// This function will be called immediately after an anonymous Hello packet is received by Bob.
///
/// Since the remote peer is anonymous at this stage of the handshake, this function is not
/// good for performing authentication and access control. Instead it should be used to mitigate
/// DDOS attacks by configuring it to return `Challenge` or `Drop` in response to an attacker's
/// Hello packet. If DDOS mitigation is not needed, this function can just be a single line that
/// returns `Allow`.
fn incoming_session(&mut self) -> IncomingSessionAction;
/// This function will be called whenever Alice's initial Hello packet contains the empty ratchet
/// fingerprint. Brand new peers will always connect to Bob with the empty ratchet, but from
@@ -178,7 +182,7 @@ pub trait ApplicationLayer: Sized {
/// least one party is misconfigured and got their ratchet keys corrupted or lost, or Bob has
/// been compromised and is being impersonated. An attacker must at least have Bob's private
/// static key to be able to ask Alice to downgrade.
fn initiator_disallows_downgrade(&mut self, session: &Arc<Session<Self::Crypto>>) -> bool;
fn initiator_disallows_downgrade(&mut self, session: &Arc<Session<Crypto>>) -> bool;
/// Function to accept sessions after final negotiation.
/// The second argument is the identity that the remote peer sent us. The application
/// must verify this identity is associated with the remote peer's static key.
@@ -187,9 +191,9 @@ pub trait ApplicationLayer: Sized {
/// before returning.
fn check_accept_session(
&mut self,
remote_static_key: &<Self::Crypto as CryptoLayer>::PublicKey,
remote_static_key: &Crypto::PublicKey,
identity: &[u8],
) -> AcceptAction<Self::Crypto>;
) -> AcceptAction<Crypto>;
/// Lookup a specific ratchet state based on its ratchet fingerprint.
/// This function will be called whenever Alice attempts to connect to us with a non-empty
@@ -217,8 +221,8 @@ pub trait ApplicationLayer: Sized {
/// function `ApplicationLayer::check_accept_session`.
fn restore_by_identity(
&mut self,
remote_static_key: &<Self::Crypto as CryptoLayer>::PublicKey,
session_data: &<Self::Crypto as CryptoLayer>::SessionData,
remote_static_key: &Crypto::PublicKey,
session_data: &Crypto::SessionData,
) -> Result<Option<RatchetStates>, std::io::Error>;
/// Atomically commit the update specified by `update_data` to storage, or return an error if
/// the update could not be made.
@@ -238,8 +242,8 @@ pub trait ApplicationLayer: Sized {
/// Otherwise, when we restart, we will not be allowed to reconnect.
fn save_ratchet_state(
&mut self,
remote_static_key: &<Self::Crypto as CryptoLayer>::PublicKey,
session_data: &<Self::Crypto as CryptoLayer>::SessionData,
remote_static_key: &Crypto::PublicKey,
session_data: &Crypto::SessionData,
update_data: RatchetUpdate<'_>,
) -> Result<(), std::io::Error>;
@@ -248,13 +252,26 @@ pub trait ApplicationLayer: Sized {
/// nothing else. Do not base protocol-level decisions upon the events passed to this function.
#[cfg(feature = "logging")]
#[allow(unused)]
fn event_log(&mut self, event: crate::LogEvent<'_, Self::Crypto>) {}
fn event_log(&mut self, event: crate::LogEvent<'_, Crypto>) {}
}
/// Possible responses that can be made to Hello packets from an anonymous peer.
#[derive(Debug, PartialEq, Eq, Clone)]
pub enum IncomingSessionAction {
/// Allow the anonymous peer to continue connecting.
///
/// In a later step, once forward secrecy is established, the peer will be forced to reveal
/// their identity.
Allow,
/// Challenge the anonymous peer to complete a proof of work and IP/Address ownership before
/// they are allowed to consume our CPU resources to process their Hello packet.
///
/// The challenge will only be effective if `Challenge` is consistently returned in response to
/// new Hello packets from the same peer or set of peers.
///
/// If they complete the challenge they will be allowed to continue connecting.
Challenge,
/// Drop the anonymous peer's Hello packet, preventing them from connecting.
Drop,
}
@@ -276,3 +293,43 @@ pub struct AcceptAction<Crypto: CryptoLayer> {
/// authentication checks.
pub responder_silently_rejects: bool,
}
/// A trait to genericize the process of repeatedly sending packet fragments on some socket or
/// network interface.
///
/// Is implemented by `FnMut(&mut [u8]) -> bool` closures.
pub trait Sender {
/// Send the given fragment on this interface and then return whether or not an error occured.
///
/// If `true` is returned then sending is cancelled and this instance of `Sender` is dropped.
fn send_frag<'a>(&'a mut self, frag: &mut [u8]) -> bool;
}
/// A trait to genericize the process of borrowing the resources necessary to repeatedly
/// send packet fragments on some socket or network interface.
///
/// Is implemented by `FnMut(&Arc<Session<Crypto>>) -> Option<(Sender, usize)>` closures.
pub trait SendTo<Crypto: CryptoLayer, S: Sender> {
/// Attempt to process and borrow the resources necessary to repeatedly send fragments of a
/// packet to the given session.
///
/// If no error occurs this function should return a `Sender` instance configured to send to the
/// remote peer specified by `session`. It should also return the MTU of this link. This MTU can
/// be `usize::MAX`, in which case the packet is not fragmented and the `Sender` instance is
/// only called once.
///
/// If `None` is returned then sending to this session is cancelled.
fn init_send<'a>(&'a mut self, session: &'a Arc<Session<Crypto>>) -> Option<(S, usize)>;
}
impl<F: FnMut(&mut [u8]) -> bool> Sender for F {
fn send_frag<'a>(&'a mut self, frag: &mut [u8]) -> bool {
self(frag)
}
}
impl<Crypto: CryptoLayer, F: FnMut(&Arc<Session<Crypto>>) -> Option<(S, usize)>, S: Sender> SendTo<Crypto, S> for F {
fn init_send<'a>(&'a mut self, session: &'a Arc<Session<Crypto>>) -> Option<(S, usize)> {
self(session)
}
}
+1 -1
View File
@@ -191,7 +191,7 @@ pub enum ReceiveOk<Crypto: CryptoLayer> {
/// or if it was a control packet that does not go through full Noise authentication.
Unassociated,
/// Packet was authentic and belongs to this specific session.
Session(Arc<Session<Crypto>>, SessionEvent),
SessionEvent(Arc<Session<Crypto>>, SessionEvent),
}
/// Something that can occur to an associated session when a packet is received successfully,
/// including receiving a payload of decrypted, authenticated data.
+13 -13
View File
@@ -343,7 +343,7 @@ fn create_a1_state<Crypto: CryptoLayer>(
Some(Box::new(StateA1 { noise, e_secret, e1_secret, identity, x1 }))
}
/// Corresponds to Transition Algorithm 1 found in Section 4.3.
pub(crate) fn trans_to_a1<Crypto: CryptoLayer, App: ApplicationLayer<Crypto = Crypto>>(
pub(crate) fn trans_to_a1<Crypto: CryptoLayer, App: ApplicationLayer<Crypto>>(
mut app: App,
ctx: &Arc<ContextInner<Crypto>>,
s_remote: Crypto::PublicKey,
@@ -443,7 +443,7 @@ pub(crate) fn respond_to_challenge<Crypto: CryptoLayer>(
}
}
/// Corresponds to Transition Algorithm 2 found in Section 4.3.
pub(crate) fn received_x1_trans<Crypto: CryptoLayer, App: ApplicationLayer<Crypto = Crypto>>(
pub(crate) fn received_x1_trans<Crypto: CryptoLayer, App: ApplicationLayer<Crypto>>(
app: &mut App,
ctx: &ContextInner<Crypto>,
hash: &mut Crypto::Hash,
@@ -595,7 +595,7 @@ pub(crate) fn received_x1_trans<Crypto: CryptoLayer, App: ApplicationLayer<Crypt
Ok(reduced_service_time)
}
/// Corresponds to Transition Algorithm 3 found in Section 4.3.
pub(crate) fn received_x2_trans<Crypto: CryptoLayer, App: ApplicationLayer<Crypto = Crypto>>(
pub(crate) fn received_x2_trans<Crypto: CryptoLayer, App: ApplicationLayer<Crypto>>(
app: &mut App,
ctx: &Arc<ContextInner<Crypto>>,
session: &Arc<Session<Crypto>>,
@@ -817,7 +817,7 @@ fn send_control<Crypto: CryptoLayer, const CAP: usize>(
}
}
/// Corresponds to Transition Algorithm 4 found in Section 4.3.
pub(crate) fn received_x3_trans<Crypto: CryptoLayer, App: ApplicationLayer<Crypto = Crypto>>(
pub(crate) fn received_x3_trans<Crypto: CryptoLayer, App: ApplicationLayer<Crypto>>(
app: &mut App,
ctx: &Arc<ContextInner<Crypto>>,
zeta: Arc<StateB2<Crypto>>,
@@ -994,7 +994,7 @@ pub(crate) fn received_x3_trans<Crypto: CryptoLayer, App: ApplicationLayer<Crypt
}
}
/// Corresponds to Transition Algorithm 5 found in Section 4.3.
pub(crate) fn received_c1_trans<Crypto: CryptoLayer, App: ApplicationLayer<Crypto = Crypto>>(
pub(crate) fn received_c1_trans<Crypto: CryptoLayer, App: ApplicationLayer<Crypto>>(
app: &mut App,
ctx: &Arc<ContextInner<Crypto>>,
session: &Arc<Session<Crypto>>,
@@ -1082,7 +1082,7 @@ pub(crate) fn received_c1_trans<Crypto: CryptoLayer, App: ApplicationLayer<Crypt
}
/// Corresponds to the trivial Transition Algorithm described for processing C_2 packets found in
/// Section 4.3.
pub(crate) fn received_c2_trans<Crypto: CryptoLayer, App: ApplicationLayer<Crypto = Crypto>>(
pub(crate) fn received_c2_trans<Crypto: CryptoLayer, App: ApplicationLayer<Crypto>>(
app: &mut App,
ctx: &Arc<ContextInner<Crypto>>,
session: &Arc<Session<Crypto>>,
@@ -1169,7 +1169,7 @@ pub(crate) fn received_d_trans<Crypto: CryptoLayer>(
Ok(())
}
// Corresponds to the timeout timer Transition Algorithm described in Section 4.1 - Definition 3.
fn timeout_trans<Crypto: CryptoLayer, App: ApplicationLayer<Crypto = Crypto>>(
fn timeout_trans<Crypto: CryptoLayer, App: ApplicationLayer<Crypto>>(
app: &mut App,
ctx: &Arc<ContextInner<Crypto>>,
session: &Arc<Session<Crypto>>,
@@ -1294,7 +1294,7 @@ fn timeout_trans<Crypto: CryptoLayer, App: ApplicationLayer<Crypto = Crypto>>(
}
}
/// Corresponds to the timer rules of the Zeta State Machine found in Section 4.1 - Definition 3.
pub(crate) fn process_timers<Crypto: CryptoLayer, App: ApplicationLayer<Crypto = Crypto>>(
pub(crate) fn process_timers<Crypto: CryptoLayer, App: ApplicationLayer<Crypto>>(
app: &mut App,
ctx: &Arc<ContextInner<Crypto>>,
session: &Arc<Session<Crypto>>,
@@ -1349,7 +1349,7 @@ pub(crate) fn process_timers<Crypto: CryptoLayer, App: ApplicationLayer<Crypto =
}
}
/// Corresponds to Transition Algorithm 7 found in Section 4.3.
pub(crate) fn received_k1_trans<Crypto: CryptoLayer, App: ApplicationLayer<Crypto = Crypto>>(
pub(crate) fn received_k1_trans<Crypto: CryptoLayer, App: ApplicationLayer<Crypto>>(
app: &mut App,
ctx: &Arc<ContextInner<Crypto>>,
session: &Arc<Session<Crypto>>,
@@ -1505,7 +1505,7 @@ pub(crate) fn received_k1_trans<Crypto: CryptoLayer, App: ApplicationLayer<Crypt
result
}
/// Corresponds to Transition Algorithm 8 found in Section 4.3.
pub(crate) fn received_k2_trans<Crypto: CryptoLayer, App: ApplicationLayer<Crypto = Crypto>>(
pub(crate) fn received_k2_trans<Crypto: CryptoLayer, App: ApplicationLayer<Crypto>>(
app: &mut App,
ctx: &Arc<ContextInner<Crypto>>,
session: &Arc<Session<Crypto>>,
@@ -1638,7 +1638,7 @@ pub(crate) fn send_payload<Crypto: CryptoLayer>(
ctx: &Arc<ContextInner<Crypto>>,
session: &Session<Crypto>,
payload: &[u8],
mut send: impl FnMut(&mut [u8]) -> bool,
mut send: impl Sender,
mtu_sized_buffer: &mut [u8],
) -> Result<bool, SendError> {
use SendError::*;
@@ -1685,7 +1685,7 @@ pub(crate) fn send_payload<Crypto: CryptoLayer>(
let header_auth = &mut mtu_sized_buffer[HEADER_AUTH_START..HEADER_AUTH_END];
state.hk_send.encrypt_in_place(header_auth.try_into().unwrap());
if !send(&mut mtu_sized_buffer[..HEADER_SIZE + fragment_len]) {
if !send.send_frag(&mut mtu_sized_buffer[..HEADER_SIZE + fragment_len]) {
return Ok(false);
}
i = j;
@@ -1704,7 +1704,7 @@ pub(crate) fn send_payload<Crypto: CryptoLayer>(
let header_auth = &mut mtu_sized_buffer[HEADER_AUTH_START..HEADER_AUTH_END];
state.hk_send.encrypt_in_place(header_auth.try_into().unwrap());
if !send(&mut mtu_sized_buffer[..HEADER_SIZE + fragment_len]) {
if !send.send_frag(&mut mtu_sized_buffer[..HEADER_SIZE + fragment_len]) {
return Ok(false);
}
+21 -21
View File
@@ -82,7 +82,7 @@ fn parse_fragment_header(incoming_fragment: &[u8]) -> Result<(usize, usize, [u8;
///
/// Corresponds to the fragmentation algorithm described in Section 6.
fn send_with_fragmentation<PrpEnc: Aes256Enc>(
mut send: impl FnMut(&mut [u8]) -> bool,
mut send: impl Sender,
mtu: usize,
headered_packet: &mut [u8],
hk_send: Option<&PrpEnc>,
@@ -108,7 +108,7 @@ fn send_with_fragmentation<PrpEnc: Aes256Enc>(
if let Some(hk_send) = hk_send {
hk_send.encrypt_in_place((&mut fragment[HEADER_AUTH_START..HEADER_AUTH_END]).try_into().unwrap());
}
if !send(fragment) {
if !send.send_frag(fragment) {
return false;
}
i = j;
@@ -151,10 +151,10 @@ impl<Crypto: CryptoLayer> Context<Crypto> {
/// object
/// * `identity` - Payload to be sent to Bob that contains the information necessary
/// for the upper protocol to authenticate and approve of Alice's identity.
pub fn open<App: ApplicationLayer<Crypto = Crypto>>(
pub fn open<App: ApplicationLayer<Crypto>>(
&self,
app: App,
send: impl FnMut(&mut [u8]) -> bool,
send: impl Sender,
mut mtu: usize,
static_remote_key: Crypto::PublicKey,
session_data: Crypto::SessionData,
@@ -190,12 +190,12 @@ impl<Crypto: CryptoLayer> Context<Crypto> {
/// * `remote_address` - Whatever the remote address is, as long as you can Hash it
/// * `incoming_fragment_buf` - Buffer containing incoming wire packet (the context takes ownership)
/// * `output_buffer` - Buffer to receive decrypted and authenticated object data
pub fn receive<'a, App: ApplicationLayer<Crypto = Crypto>, SendFn: FnMut(&mut [u8]) -> bool>(
pub fn receive<'a, App: ApplicationLayer<Crypto>, S: Sender>(
&self,
mut app: App,
mut send_unassociated_reply: impl FnMut(&mut [u8]) -> bool,
mut send_unassociated_reply: impl Sender,
mut send_unassociated_mtu: usize,
mut send_to: impl FnMut(&Arc<Session<Crypto>>) -> Option<(SendFn, usize)>,
mut send_to: impl SendTo<Crypto, S>,
remote_address: &impl Hash,
mut incoming_fragment_buf: Crypto::IncomingPacketBuffer,
output_buffer: impl Write,
@@ -317,9 +317,9 @@ impl<Crypto: CryptoLayer> Context<Crypto> {
};
let send_associated = |packet: &mut [u8], hk_send: Option<&Crypto::PrpEnc>| {
if let Some((send_fragment, mut mtu)) = send_to(&session) {
if let Some((sender, mut mtu)) = send_to.init_send(&session) {
mtu = mtu.max(MIN_TRANSPORT_MTU);
send_with_fragmentation(send_fragment, mtu, packet, hk_send);
send_with_fragmentation(sender, mtu, packet, hk_send);
}
};
match packet_type {
@@ -403,7 +403,7 @@ impl<Crypto: CryptoLayer> Context<Crypto> {
_ => return Err(fault!(InvalidPacket, true)), // This is unreachable.
}
};
Ok((ReceiveOk::Session(session, ret.0), ret.1))
Ok((ReceiveOk::SessionEvent(session, ret.0), ret.1))
} else {
// Check for and handle PACKET_TYPE_ALICE_NOISE_XK_PATTERN_3
let zeta = self.0.unassociated_handshake_states.get(kid_recv);
@@ -463,7 +463,7 @@ impl<Crypto: CryptoLayer> Context<Crypto> {
})?;
log!(app, X3IsAuthSentKeyConfirm(&session));
Ok((
ReceiveOk::Session(
ReceiveOk::SessionEvent(
session,
if should_warn_missing_ratchet {
SessionEvent::NewDowngradedSession
@@ -552,7 +552,7 @@ impl<Crypto: CryptoLayer> Context<Crypto> {
.copy_from_slice(&nonce[..PACKET_NONCE_SIZE]);
set_header(&mut challenge_packet, 0, &nonce);
send_unassociated_reply(&mut challenge_packet);
send_unassociated_reply.send_frag(&mut challenge_packet);
// If we issue a challenge the first hello packet will always fail.
return Err(fault!(FailedAuth, false));
} else {
@@ -611,7 +611,7 @@ impl<Crypto: CryptoLayer> Context<Crypto> {
pub fn send(
&self,
session: &Session<Crypto>,
send: impl FnMut(&mut [u8]) -> bool,
send: impl Sender,
mtu_sized_buffer: &mut [u8],
data: &[u8],
) -> Result<bool, SendError> {
@@ -625,10 +625,10 @@ impl<Crypto: CryptoLayer> Context<Crypto> {
///
/// * `app` - Interface to application using ZSSP
/// * `send_to` - Function to get a sender and an MTU to send something over an active session
pub fn service<App: ApplicationLayer<Crypto = Crypto>, SendFn: FnMut(&mut [u8]) -> bool>(
pub fn service<App: ApplicationLayer<Crypto>, S: Sender>(
&self,
mut app: App,
send_to: impl FnMut(&Arc<Session<Crypto>>) -> Option<(SendFn, usize)>,
send_to: impl SendTo<Crypto, S>,
) -> i64 {
let current_time = app.time();
let next_service_time = self.service_inner(app, send_to, current_time);
@@ -649,18 +649,18 @@ impl<Crypto: CryptoLayer> Context<Crypto> {
///
/// * `app` - Interface to application using ZSSP
/// * `send_to` - Function to get a sender and an MTU to send something over an active session
pub fn service_scheduled<App: ApplicationLayer<Crypto = Crypto>, SendFn: FnMut(&mut [u8]) -> bool>(
pub fn service_scheduled<App: ApplicationLayer<Crypto>, S: Sender>(
&self,
mut app: App,
send_to: impl FnMut(&Arc<Session<Crypto>>) -> Option<(SendFn, usize)>,
send_to: impl SendTo<Crypto, S>
) -> i64 {
let current_time = app.time();
self.service_inner(app, send_to, current_time)
}
fn service_inner<App: ApplicationLayer<Crypto = Crypto>, SendFn: FnMut(&mut [u8]) -> bool>(
fn service_inner<App: ApplicationLayer<Crypto>, S: Sender>(
&self,
mut app: App,
mut send_to: impl FnMut(&Arc<Session<Crypto>>) -> Option<(SendFn, usize)>,
mut send_to: impl SendTo<Crypto, S>,
current_time: i64,
) -> i64 {
let ctx = &self.0;
@@ -682,9 +682,9 @@ impl<Crypto: CryptoLayer> Context<Crypto> {
}
};
let result = process_timers(&mut app, ctx, &session, current_time, |packet, hk_send| {
if let Some((send_fragment, mut mtu)) = send_to(&session) {
if let Some((sender, mut mtu)) = send_to.init_send(&session) {
mtu = mtu.max(MIN_TRANSPORT_MTU);
send_with_fragmentation(send_fragment, mtu, packet, hk_send);
send_with_fragmentation(sender, mtu, packet, hk_send);
}
});
if let Some(next_timer) = result {