From fb1096f9a30b106dce3b1b9cc765edb4d65d8f56 Mon Sep 17 00:00:00 2001 From: Avril Date: Fri, 23 Apr 2021 15:52:29 +0100 Subject: [PATCH] begin future for exchanging chacha20 keys --- src/crypt.rs | 15 ++++++++++++ src/stream.rs | 24 +++++++++++++++++-- src/stream/exchange.rs | 40 ++++++++++++++++++++++++++++++++ src/stream/traits.rs | 52 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 129 insertions(+), 2 deletions(-) create mode 100644 src/stream/exchange.rs diff --git a/src/crypt.rs b/src/crypt.rs index a986111..aa1db11 100644 --- a/src/crypt.rs +++ b/src/crypt.rs @@ -1,4 +1,8 @@ use super::*; +use std::io::{ + self, + Write, +}; /// TODO: RSA private key pub type RsaPrivateKey = (); @@ -6,7 +10,18 @@ pub type RsaPrivateKey = (); /// TODO: RSA public key pub type RsaPublicKey = (); +pub(crate) fn rsa_encrypt(with: &RsaPublicKey, to: &mut W, buf: &[u8]) -> io::Result +{ + todo!() +} + pub(crate) fn generate() -> RsaPrivateKey { todo!() } + +pub use chacha20stream::{ + Key, + IV, + keygen as chacha_keygen, +}; diff --git a/src/stream.rs b/src/stream.rs index 85ec774..72935a3 100644 --- a/src/stream.rs +++ b/src/stream.rs @@ -21,6 +21,8 @@ use crypt::{ mod traits; pub use traits::*; +mod exchange; + /// Combined Read + Write encryptable async stream. /// /// The `AsyncRead` and `AsyncWrite` impls of this type forward to the backing impls for `S`. @@ -35,10 +37,28 @@ pub struct Stream #[pin] stream: S, } +/// `Stream` with enabled encryption. +pub struct EncryptedStream<'a, S> +{ + read_cipher: Crypter, + write_cipher: Crypter, + + write_crypt_buf_ptr: SliceMeta, + write_crypt_buffer: Vec, + + backing: &'a mut Stream, +} + impl Stream> where Tx: AsyncWrite, Rx: AsyncRead { + /// Exchange RSA keys through this stream. + pub async fn exchange(&mut self) -> io::Result<()> + { + todo!() + } + /// Merge an `AsyncWrite`, and `AsyncRead` stream into `Stream`. pub fn merged(tx: Tx, rx: Rx) -> Self { @@ -48,7 +68,7 @@ where Tx: AsyncWrite, } } } - +/* impl Stream where S: Split, S::First: AsyncWrite, @@ -90,7 +110,7 @@ impl Stream meta: self.meta }.split() } -} +}*/ impl Split for Stream where S: Split, diff --git a/src/stream/exchange.rs b/src/stream/exchange.rs new file mode 100644 index 0000000..3d41a61 --- /dev/null +++ b/src/stream/exchange.rs @@ -0,0 +1,40 @@ +//! RSA and chacha20 key exchange methods +use super::*; +/* +use tokio::prelude::*; + +pub async fn write_cckey(mut to: W, rsa: &crypt::RsaPublicKey, key: &crypt::Key, iv: &crypt::IV) -> std::io::Result<()> +{ + let key = { + let mut buf = Vec::with_capacity(chacha20stream::key::KEY_SIZE); + crypt::rsa_encrypt(rsa, &mut buf, key.as_ref())?; + buf + }; + + to.write_all(&key[..]).await?; //TODO: Find size of `key` here. + to.write_all(iv.as_ref()).await?; + + Ok(()) +} + */ + +/// A future that writes an RSA encrypted chacha20 key to a stream when awaited +//TODO: Find size of RSA ecnrypted chacha `Key`. +#[pin_project] +struct CCKeyWrite<'a, W: AsyncWrite>{ + /// The bytes of an **already encrypted** chacha20 key. + enc_key: Vec, + /// A non-encrypted chacha20 IV. + iv: [u8; chacha20stream::key::IV_SIZE], + + /// Stream to write the data to when this future is awaited. + #[pin] stream: &'a mut W, +} + +//TODO: impl `Future` for CCKeyWrite should `write_all` both `enc_key` and `iv` to `stream` when `.await`ed. +impl<'a, W: AsyncWrite> Future for CCKeyWrite<'a, S> +{ + type Output = io::Result<()>; + + //todo: how to we `write_all` in `poll`? implement it outselves with looping `poll_write` and `futures::ready!()`? +} diff --git a/src/stream/traits.rs b/src/stream/traits.rs index f2a9e0b..602a43f 100644 --- a/src/stream/traits.rs +++ b/src/stream/traits.rs @@ -99,3 +99,55 @@ where Rx: AsyncRead self.rx().poll_read_buf(cx, buf) } } + +/* +pub(super) enum MaybeFullWrite<'a, S: AsyncWrite> +{ + Full(&'a mut Stream), + Half(&'a mut WriteHalf), +} + +pub(super) enum MaybeFullRead<'a, S: AsyncRead> +{ + Full(&'a mut Stream), + Half(&'a mut ReadHalf), +} + +impl<'a, S: AsyncRead> AsMut for MaybeFullRead<'a, S> +{ + #[inline] fn as_mut(&mut self) -> &mut (dyn AsyncRead + 'a) + { + self.as_dyn() + } +} + +impl<'a, S: AsyncWrite> AsMut for MaybeFullWrite<'a, S> +{ + #[inline] fn as_mut(&mut self) -> &mut (dyn AsyncWrite + 'a) + { + self.as_dyn() + } +} + + +impl<'a, S: AsyncRead> MaybeFullRead<'a, S> +{ + #[inline(always)] fn as_dyn(&mut self) -> &mut (dyn AsyncRead + 'a) + { + match self { + Self::Full(f) => f, + Self::Half(h) => h, + } + } +} +impl<'a, S: AsyncWrite> MaybeFullWrite<'a, S> +{ + #[inline(always)] fn as_dyn(&mut self) -> &mut (dyn AsyncWrite + 'a) + { + match self { + Self::Full(f) => f, + Self::Half(h) => h, + } + } +} +*/