@ -29,6 +29,9 @@ use std::{
marker ::Unpin ,
} ;
/// Max size to read when exchanging keys
const TRANS_KEY_MAX_SIZE : usize = 4096 ;
/// Encrypted socket information.
#[ derive(Debug) ]
struct ESockInfo {
@ -48,6 +51,85 @@ pub struct ESock<W, R> {
tx : AsyncSink < W > ,
}
impl < W : AsyncWrite , R : AsyncRead > ESock < W , R >
{
pub fn inner ( & self ) -> ( & W , & R )
{
( self . tx . inner ( ) , self . rx . inner ( ) )
}
fn inner_mut ( & mut self ) -> ( & mut W , & mut R )
{
( self . tx . inner_mut ( ) , self . rx . inner_mut ( ) )
}
/// Create a future that exchanges keys
pub fn exchange ( & mut self ) -> Exchange < ' _ , W , R >
{
Exchange { sock : self }
}
}
impl < W : AsyncWrite + Unpin , R : AsyncRead + Unpin > ESock < W , R >
{
/// Exchange keys.
pub async fn exchange_unpin ( & mut self ) -> eyre ::Result < ( ) >
{
use tokio ::prelude ::* ;
let our_key = self . info . read ( ) . await . us . get_public_parts ( ) ;
let ( tx , rx ) = self . inner_mut ( ) ;
let read_fut = {
async move {
// Read the public key from `rx`.
//TODO: Find pubkey max size.
let mut sz_buf = [ 0 u8 ; std ::mem ::size_of ::< u64 > ( ) ] ;
rx . read_exact ( & mut sz_buf [ .. ] ) . await ? ;
let sz = match usize ::try_from ( u64 ::from_be_bytes ( sz_buf ) ) ? {
x if x > TRANS_KEY_MAX_SIZE = > return Err ( eyre ! ( "Recv'd key size exceeded max" ) ) ,
x = > x
} ;
let mut key_bytes = Vec ::with_capacity ( sz ) ;
tokio ::io ::copy ( & mut rx . take ( sz as u64 ) , & mut key_bytes ) . await ? ;
if key_bytes . len ( ) ! = sz {
return Err ( eyre ! ( "Could not read required bytes" ) ) ;
}
let k = RsaPublicKey ::from_bytes ( key_bytes ) ? ;
Result ::< RsaPublicKey , eyre ::Report > ::Ok ( k )
}
} ;
let write_fut = {
let key_bytes = our_key . to_bytes ( ) ;
assert! ( key_bytes . len ( ) < = TRANS_KEY_MAX_SIZE ) ;
let sz_buf = u64 ::try_from ( key_bytes . len ( ) ) ? . to_be_bytes ( ) ;
async move {
tx . write_all ( & sz_buf [ .. ] ) . await ? ;
tx . write_all ( & key_bytes [ .. ] ) . await ? ;
Result ::< ( ) , eyre ::Report > ::Ok ( ( ) )
}
} ;
let ( send , recv ) = tokio ::join ! [ write_fut , read_fut ] ;
send ? ;
let recv = recv ? ;
self . info . write ( ) . await . them = Some ( recv ) ;
Ok ( ( ) )
}
}
pub struct Exchange < ' a , W , R >
{
sock : & ' a mut ESock < W , R > ,
}
impl < ' a , W : AsyncWrite , R : AsyncRead > Future for Exchange < ' a , W , R >
{
type Output = eyre ::Result < ( ) > ;
fn poll ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < Self ::Output > {
todo! ( "This is going to be dificult to implement... We don't have access to write_all and read_exact" )
}
}
/// Write half for `ESock`.
#[ pin_project ]
#[ derive(Debug) ]