diff --git a/src/crypt.rs b/src/crypt.rs new file mode 100644 index 0000000..533973d --- /dev/null +++ b/src/crypt.rs @@ -0,0 +1,7 @@ +use super::*; + +/// TODO: RSA private key +pub type RsaPrivateKey = (); + +/// TODO: RSA public key +pub type RsaPublicKey = (); diff --git a/src/dual.rs b/src/dual.rs index e07d50c..81dc362 100644 --- a/src/dual.rs +++ b/src/dual.rs @@ -24,7 +24,7 @@ bool_type!(pub Encryption; "What way are we en/decrypting?" => Encrypt, Decrypt) /// This will prevent the need to check the discriminant of the enum each time the `DualStream`'s `AsyncWrite` methods are polled. /// The type implements `AsRef/Mut` for streams `S` that are both `Unpin` and not `Unpin` for convenience. #[derive(Debug)] -pub enum DualStream +pub enum DualStream { /// If there is a panic while switching modes, the stream is left in this invariant state. /// diff --git a/src/lib.rs b/src/lib.rs index aba720b..6cecaf6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,5 +5,24 @@ #[macro_use] mod ext; #[allow(unused_imports)] use ext::*; +use std::sync::Arc; +use tokio::io::{AsyncWrite, AsyncRead}; +use openssl::symm::Crypter; + // Wrapper for plain/symm-enc stream swapping mod dual; +// Crypto shit +mod crypt; +// Stream impls +mod stream; + + +/// A type that implements both `AsyncWrite` and `AsyncRead` +pub trait AsyncStream: AsyncRead + AsyncWrite{} +impl AsyncStream for T{} + +pub use stream::{ + EncryptedStream, + WriteHalf, + ReadHalf, +}; diff --git a/src/stream.rs b/src/stream.rs new file mode 100644 index 0000000..647414a --- /dev/null +++ b/src/stream.rs @@ -0,0 +1,61 @@ +use super::*; +use crypt::{ + RsaPublicKey, + RsaPrivateKey, +}; + +/// Inner rsa data for encrypted stream read+write halves +struct EncryptedStreamMeta +{ + us: RsaPrivateKey, + them: Option, +} + +/// Writable half of `EncryptedStream`. +pub struct WriteHalf +where S: AsyncWrite +{ + meta: Arc, + + backing_write: Box>, +} + +/// Readable half of `EncryptedStream`. +pub struct ReadHalf +where S: AsyncRead +{ + meta: Arc, + + /// chacha20_poly1305 decrypter for incoming reads from `S` + //TODO: chacha20stream: implement a read version of AsyncSink so we don't need to keep this? + cipher: Option, + backing_read: Box, +} + +struct ReadWriteCombined +{ + /// Since chacha20stream has no AsyncRead counterpart, we have to do it ourselves. + cipher_read: Option, + backing_read: R, + + backing_write: dual::DualStream, +} + +/// RSA/chacha20 encrypted stream +pub struct EncryptedStream +where S: AsyncStream +{ + meta: EncryptedStreamMeta, + + // Keep the streams on the heap to keep this type not hueg. + backing: Box>, +} + +impl EncryptedStream +{ + /// Has this stream done its RSA key exchange? + pub fn has_exchanged(&self) -> bool + { + self.meta.them.is_some() + } +}