mirror of
https://github.com/zerotier/zssp.git
synced 2026-05-22 16:28:40 -07:00
added a more flexible trait to handle sending
This commit is contained in:
@@ -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))
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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))
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
@@ -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
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user