diff --git a/Cargo.lock b/Cargo.lock index a08f729..86a8401 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -206,9 +206,9 @@ dependencies = [ [[package]] name = "cryptohelpers" -version = "1.2.0" +version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ef6d4c394fce0d9b42b9bd7242df5201b6c4996d1b9f63ac75c83ba9e6b05ce" +checksum = "0bc52622422e80c9a71f9664e3b90a77465b3ea4f05f06591987395eda0ff0f2" dependencies = [ "crc", "getrandom", diff --git a/Cargo.toml b/Cargo.toml index 6c5943e..3100722 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,7 +15,7 @@ local-time = [] [dependencies] color-eyre = "0.5.3" lazy_static = "1.4.0" -crypto = {package= "cryptohelpers", version = "1.2", features=["full", "async", "serialise"]} +crypto = {package= "cryptohelpers", version = "1.3", features=["full", "async", "serialise"]} cfg-if = "0.1.10" tokio = {version = "0.2", features=["full"]} serde = {version ="1.0.116", features=["derive"]} diff --git a/src/format/key/mod.rs b/src/format/key/mod.rs index 17f142b..a36e289 100644 --- a/src/format/key/mod.rs +++ b/src/format/key/mod.rs @@ -82,7 +82,7 @@ impl Header for KeyHeader fn hash(&self) -> Sha256Hash { let mut output = Vec::new(); - self.write_bytes(&mut output).now_or_never().unwrap().expect("Failed to write bytes to in-memory buffer"); + self.write_bytes(&mut output, None).now_or_never().unwrap().expect("Failed to write bytes to in-memory buffer"); crypto::sha256::compute_slice(output) } } @@ -136,7 +136,7 @@ impl KeyHeader /// Write this superheader as text bytes to this stream #[instrument(err, skip(out))] - pub async fn write_text(&self, out: &mut T) -> Result + pub async fn write_text(&self, out: &mut T, passwd: Option<&Password>) -> Result { let text = serialise::into_text(self) .wrap_err_with(|| eyre::eyre!("Failed to serialise header to text")) @@ -157,8 +157,8 @@ impl KeyHeader Ok(written + 4) } /// Read a superheader as text bytes from this stream - #[instrument(err, skip(input))] - pub async fn read_text(input: &mut T) -> Result + #[instrument(err, skip(input, passwd))] + pub async fn read_text Option>(input: &mut T, passwd: F) -> Result { let (mut tx, mut rx) = mpsc::channel(1); @@ -302,7 +302,7 @@ impl KeyHeader } /// Write this key header as bytes to this stream #[instrument(err, skip(out))] - pub async fn write_bytes(&self, out: &mut T) -> Result + pub async fn write_bytes(&self, out: &mut T, passwd: Option<&Password>) -> Result { out.write_u8(self.kind as u8).await?; let desc = { @@ -321,8 +321,8 @@ impl KeyHeader } /// Read a key header as bytes from this stream - #[instrument(err, skip(input))] - pub async fn read_bytes(input: &mut T) -> Result + #[instrument(err, skip(input, passwd))] + pub async fn read_bytes Option>(input: &mut T, passwd: F) -> Result { let kind = { let byte = input.read_u8().await?; @@ -361,27 +361,27 @@ impl KeyHeader impl serialise::BinarySerialisable for KeyHeader { - #[inline(always)] fn serialise_bytes<'a, 'b: 'a, T: AsyncWrite+Unpin+?Sized>(&'a self, out: &'b mut T) -> LocalBoxFuture<'a, Result> + #[inline(always)] fn serialise_bytes<'a, 'b: 'a, T: AsyncWrite+Unpin+?Sized>(&'a self, out: &'b mut T, passwd: Option<&'b Password>) -> LocalBoxFuture<'a, Result> { - self.write_bytes(out).boxed_local() + self.write_bytes(out, passwd).boxed_local() } - #[inline(always)] fn deserialise_bytes<'b , T: AsyncRead+Unpin+?Sized>(input: &'b mut T) -> LocalBoxFuture<'b, Result> + #[inline(always)] fn deserialise_bytes<'b , T: AsyncRead+Unpin+?Sized, F: for<'r> FnOnce(&'r Salt) -> Option+ 'b>(input: &'b mut T, passwd: F) -> LocalBoxFuture<'b, Result> where Self: 'b { - Self::read_bytes(input).boxed_local() + Self::read_bytes(input, passwd).boxed_local() } } impl serialise::TextSerialiseable for KeyHeader { - #[inline(always)] fn serialise_text<'a, 'b: 'a, T: AsyncWrite+Unpin+?Sized>(&'a self, out: &'b mut T) -> LocalBoxFuture<'a, Result> + #[inline(always)] fn serialise_text<'a, 'b: 'a, T: AsyncWrite+Unpin+?Sized>(&'a self, out: &'b mut T, passwd: Option<&'b Password>) -> LocalBoxFuture<'a, Result> { - self.write_text(out).boxed_local() + self.write_text(out, passwd).boxed_local() } - #[inline(always)] fn deserialise_text<'a, T: AsyncBufRead+Unpin+?Sized>(input: &'a mut T) -> LocalBoxFuture<'a, Result> + #[inline(always)] fn deserialise_text<'a, T: AsyncBufRead+Unpin+?Sized, F: for<'r> FnOnce(&'r Salt) -> Option + 'a>(input: &'a mut T, passwd: F) -> LocalBoxFuture<'a, Result> where Self: 'a { - Self::read_text(input).boxed_local() + Self::read_text(input, passwd).boxed_local() } } @@ -414,17 +414,18 @@ mod tests let header = KeyHeader::new_now(KeyHeaderKind::Aes, Default::default(), Default::default()); let mut ser = Vec::new(); + let password = Password::derive("hello world", &Default::default()); let superheader = SuperHeader::::new_for(&header); println!("Writing: {:?} + {:?}", superheader, header); - let written = superheader.serialise_bytes(&mut ser).await? + - header.write_bytes(&mut ser).await?; + let written = superheader.serialise_bytes(&mut ser, Some(&password)).await? + + header.write_bytes(&mut ser,Some(&password)).await?; println!("Wrote {} bytes", written); println!("{}\n", ser.fmt_view()); let mut read = &ser[..]; - let reads = SuperHeader::deserialise_bytes(&mut read).await?; + let reads = SuperHeader::deserialise_bytes(&mut read, |_| Some(password.clone())).await?; println!("Read super: {:?}", reads); - let readheader = KeyHeader::deserialise_bytes(&mut read).await?; + let readheader = KeyHeader::deserialise_bytes(&mut read, |_| Some(password.clone())).await?; println!("Read real: {:?}", readheader); reads.verify_for(&header)?; @@ -440,11 +441,11 @@ mod tests let header = KeyHeader::new_now(KeyHeaderKind::Aes, Default::default(), Default::default()); let mut ser = Vec::new(); println!("Writing {:?}", header); - let val = header.write_bytes(&mut ser).await?; + let val = header.write_bytes(&mut ser, None).await?; println!("Wrote {} bytes:", val); println!("{}\n", ser.fmt_view()); - let reader = KeyHeader::read_bytes(&mut &ser[..]).await?; + let reader = KeyHeader::read_bytes(&mut &ser[..], |_| None).await?; println!("Read: {:?}", reader); assert_eq!(reader, header); @@ -457,11 +458,11 @@ mod tests let header = KeyHeader::new_now(KeyHeaderKind::Aes, Default::default(), Default::default()); let mut ser = Vec::new(); println!("Writing {:?}", header); - let val = header.write_text(&mut ser).await?; + let val = header.write_text(&mut ser, None).await?; println!("Wrote {} bytes:", val); println!("{}\n", ser.fmt_view()); - let reader = KeyHeader::read_text(&mut &ser[..]).await?; + let reader = KeyHeader::read_text(&mut &ser[..], |_| None).await?; println!("Read: {:?}", reader); assert_eq!(reader, header); @@ -476,16 +477,16 @@ mod tests let mut ser = Vec::new(); let superheader = SuperHeader::::new_for(&header); println!("Writing: {:?} + {:?}", superheader, header); - let written = superheader.write_text(&mut ser).await?; - ser.extend(header.into_memory(serialise::Mode::Text)?); //header.write_text(&mut ser).await?; + let written = superheader.write_text(&mut ser, None).await?; + ser.extend(header.into_memory(serialise::Mode::Text, None)?); //header.write_text(&mut ser).await?; println!("Wrote {} bytes", written); println!("{}\n", ser.fmt_view()); let mut read = &ser[..]; - let (reads, readn) = SuperHeader::from_memory(&mut read, serialise::Mode::Text)?; // SuperHeader::read_text(read).await?; + let (reads, readn) = SuperHeader::from_memory(&mut read, serialise::Mode::Text, |_| None)?; // SuperHeader::read_text(read).await?; let mut read = &read[readn..]; println!("Read super: {:?}", reads); - let readheader = KeyHeader::read_text(&mut read).await?; + let readheader = KeyHeader::read_text(&mut read, |_| None).await?; println!("Read real: {:?}", readheader); reads.verify_for(&header)?; diff --git a/src/format/mod.rs b/src/format/mod.rs index 7e8dfea..f3fe7e9 100644 --- a/src/format/mod.rs +++ b/src/format/mod.rs @@ -20,7 +20,7 @@ use tokio::{ }, }; use version::Version; - +use crypto::password::{Password,Salt}; /// Trait RAE headers implement pub trait Header: fmt::Debug @@ -73,7 +73,7 @@ impl SuperHeader { /// Write this superheader as text bytes to this stream #[instrument(err, skip(out))] - pub async fn write_text(&self, out: &mut T) -> Result + pub async fn write_text(&self, out: &mut T, passwd: Option<&Password>) -> Result { let string = format!(r#"--- {} v{}-{:x} ({}) {} --- "#, std::str::from_utf8(&self.head[..]) @@ -88,8 +88,8 @@ impl SuperHeader Ok(string.len()) } /// Read a superheader as text bytes from this stream - #[instrument(err, skip(input))] - pub async fn read_text(input: &mut T) -> Result + #[instrument(err, skip(input, passwd))] + pub async fn read_text Option>(input: &mut T, passwd: F) -> Result { let mut line = String::new(); input.read_line(&mut line).await?; @@ -198,7 +198,7 @@ impl SuperHeader /// Write this superheader as bytes to this stream #[instrument(err, skip(out))] - pub async fn write_bytes(&self, out: &mut T) -> Result + pub async fn write_bytes(&self, out: &mut T, passwd: Option<&Password>) -> Result { Ok({out.write_all(&self.head[..]).await?; self.head.len()} + {out.write_all(self.vers.as_bytes()).await?; std::mem::size_of::()} + @@ -206,8 +206,8 @@ impl SuperHeader {out.write_all(self.header_hash.as_ref()).await?; std::mem::size_of::()}) } /// Read a superheader as bytes from this stream - #[instrument(err, skip(input))] - pub async fn read_bytes(input: &mut T) -> Result + #[instrument(err, skip(input, passwd))] + pub async fn read_bytes Option>(input: &mut T, passwd: F) -> Result { let mut new = Self::new(); input.read_exact(&mut new.head[..]).await?; @@ -323,27 +323,27 @@ impl fmt::Display for VerificationError impl serialise::BinarySerialisable for SuperHeader { - #[inline(always)] fn serialise_bytes<'a, 'b: 'a, T: AsyncWrite+Unpin+?Sized>(&'a self, out: &'b mut T) -> LocalBoxFuture<'a, Result> + #[inline(always)] fn serialise_bytes<'a, 'b: 'a, T: AsyncWrite+Unpin+?Sized>(&'a self, out: &'b mut T, passwd: Option<&'b Password>) -> LocalBoxFuture<'a, Result> { - self.write_bytes(out).boxed_local() + self.write_bytes(out, passwd).boxed_local() } - #[inline(always)] fn deserialise_bytes<'b , T: AsyncRead+Unpin+?Sized>(input: &'b mut T) -> LocalBoxFuture<'b, Result> + #[inline(always)] fn deserialise_bytes<'b , T: AsyncRead+Unpin+?Sized, F: for<'r> FnOnce(&'r Salt) -> Option + 'b>(input: &'b mut T, passwd: F) -> LocalBoxFuture<'b, Result> where Self: 'b { - Self::read_bytes(input).boxed_local() + Self::read_bytes(input, passwd).boxed_local() } } impl serialise::TextSerialiseable for SuperHeader { - #[inline(always)] fn serialise_text<'a, 'b: 'a, T: AsyncWrite+Unpin+?Sized>(&'a self, out: &'b mut T) -> LocalBoxFuture<'a, Result> + #[inline(always)] fn serialise_text<'a, 'b: 'a, T: AsyncWrite+Unpin+?Sized>(&'a self, out: &'b mut T, passwd: Option<&'b Password>) -> LocalBoxFuture<'a, Result> { - self.write_text(out).boxed_local() + self.write_text(out, passwd).boxed_local() } - #[inline(always)] fn deserialise_text<'a, T: AsyncBufRead+Unpin+?Sized>(input: &'a mut T) -> LocalBoxFuture<'a, Result> + #[inline(always)] fn deserialise_text<'a, T: AsyncBufRead+Unpin+?Sized, F: for<'r> FnOnce(&'r Salt) -> Option + 'a>(input: &'a mut T, passwd: F) -> LocalBoxFuture<'a, Result> where Self: 'a { - Self::read_text(input).boxed_local() + Self::read_text(input, passwd).boxed_local() } } diff --git a/src/main.rs b/src/main.rs index 618947e..7d70849 100644 --- a/src/main.rs +++ b/src/main.rs @@ -148,16 +148,16 @@ async fn fuck() -> eyre::Result<()> let mut ser = Vec::new(); let superheader = SuperHeader::::new_for(&header); println!("Writing: {:?} + {:?}", superheader, header); - let written = superheader.write_text(&mut ser).await?; - ser.extend(header.into_memory(serialise::Mode::Text)?); //header.write_text(&mut ser).await?; + let written = superheader.write_text(&mut ser, None).await?; + ser.extend(header.into_memory(serialise::Mode::Text, None)?); //header.write_text(&mut ser).await?; println!("Wrote {} bytes", written); println!("{}\n", ser.fmt_view()); let mut read = &ser[..]; - let (reads, readn) = SuperHeader::from_memory(&mut read, serialise::Mode::Text)?; // SuperHeader::read_text(read).await?; + let (reads, readn) = SuperHeader::from_memory(&mut read, serialise::Mode::Text, |_| None)?; // SuperHeader::read_text(read).await?; let mut read = &read[readn..]; println!("Read super: {:?}", reads); - let readheader = KeyHeader::read_text(&mut read).await?; + let readheader = KeyHeader::read_text(&mut read, |_| None).await?; println!("Read real: {:?}", readheader); reads.verify_for(&header)?; diff --git a/src/serialise.rs b/src/serialise.rs index cd06475..1e737ee 100644 --- a/src/serialise.rs +++ b/src/serialise.rs @@ -5,13 +5,23 @@ use std::{ marker::Unpin, fmt, }; +use crypto::{ + password::{ + Salt, + Password, + }, +}; + +///// The callback to get a derrived password +//pub trait PasswordFn: for<'r> FnOnce(&'r Salt) -> Option{} +//impl FnOnce(&'r Salt) -> Option> PasswordFn for T{} +// ^ -- super dumb awful unhelpful error messages trying to do this, so fuck it copy & paste it is pub trait TextSerialiseable: Sized { - fn serialise_text<'a, 'b: 'a, T: AsyncWrite+Unpin+?Sized>(&'a self, out: &'b mut T) -> LocalBoxFuture<'a, Result>; - fn deserialise_text<'a, T: AsyncBufRead+Unpin+?Sized>(input: &'a mut T) -> LocalBoxFuture<'a, Result> + fn serialise_text<'a, 'b: 'a, T: AsyncWrite+Unpin+?Sized>(&'a self, out: &'b mut T, passwd: Option<&'b Password>) -> LocalBoxFuture<'a, Result>; + fn deserialise_text<'a, T: AsyncBufRead+Unpin+?Sized, F: for<'r> FnOnce(&'r Salt) -> Option + 'a>(input: &'a mut T, passwd: F) -> LocalBoxFuture<'a, Result> where Self: 'a; - #[inline] fn size_hint(&self) -> (usize, Option) { (0,None) @@ -21,9 +31,9 @@ pub trait TextSerialiseable: Sized pub trait BinarySerialisable: Sized { - fn serialise_bytes<'a, 'b, T: AsyncWrite+Unpin+?Sized>(&'a self, out: &'b mut T) -> LocalBoxFuture<'a, Result> + fn serialise_bytes<'a, 'b, T: AsyncWrite+Unpin+?Sized>(&'a self, out: &'b mut T, passwd: Option<&'b Password>) -> LocalBoxFuture<'a, Result> where 'b: 'a; - fn deserialise_bytes<'b , T: AsyncRead+Unpin+?Sized>(input: &'b mut T) -> LocalBoxFuture<'b, Result> + fn deserialise_bytes<'b , T: AsyncRead+Unpin+?Sized, F: for<'r> FnOnce(&'r Salt) -> Option + 'b>(input: &'b mut T, passwd: F) -> LocalBoxFuture<'b, Result> where Self: 'b; #[inline] fn size_hint(&self) -> (usize, Option) @@ -42,7 +52,7 @@ pub trait Serialisable: BinarySerialisable + TextSerialiseable /// # Notes /// This function will fail if any `await`ed future within the `serialise_*` method cannot complete immediately. #[instrument(skip(self))] - fn into_memory(&self, mode: Mode) -> Result, eyre::Report> + fn into_memory(&self, mode: Mode, passwd: Option<&Password>) -> Result, eyre::Report> { let mut output = match mode.size_hint(self) { @@ -52,8 +62,8 @@ pub trait Serialisable: BinarySerialisable + TextSerialiseable trace!("Cap for membuf is {} bytes", output.capacity()); let note = || format!("While serialising {} into memory", std::any::type_name::()); let written = match mode { - Mode::Text => self.serialise_text(&mut output).now_or_never(), - Mode::Binary => self.serialise_bytes(&mut output).now_or_never(), + Mode::Text => self.serialise_text(&mut output, passwd).now_or_never(), + Mode::Binary => self.serialise_bytes(&mut output, passwd).now_or_never(), } .ok_or_else(|| eyre::eyre!("Failed to complete {} write syncronously. A future returned `Poll::Pending`.", mode)) .with_note(note.clone())? @@ -72,8 +82,8 @@ pub trait Serialisable: BinarySerialisable + TextSerialiseable /// /// # Notes /// This function will fail if any `await`ed future within the `deserialise_*` method cannot complete immediately. - #[instrument(skip(buf),fields(buf = ?buf.as_ref()))] - fn from_memory>(buf: T, mode: Mode) -> Result<(Self, usize), eyre::Report> + #[instrument(skip(buf, passwd),fields(buf = ?buf.as_ref()))] + fn from_memory, F: FnOnce(&Salt) -> Option>(buf: T, mode: Mode, passwd: F) -> Result<(Self, usize), eyre::Report> { let buf = buf.as_ref(); let mut reader = &buf[..]; @@ -83,8 +93,8 @@ pub trait Serialisable: BinarySerialisable + TextSerialiseable let bytes = || format!("{}", buf.fmt_view()).header("Binary buffer was"); let text = || String::from_utf8_lossy(buf).into_owned().header("Text buffer was"); let value = match mode { - Mode::Binary => Self::deserialise_bytes(&mut reader).now_or_never(), - Mode::Text => Self::deserialise_text(&mut reader).now_or_never(), + Mode::Binary => Self::deserialise_bytes(&mut reader, passwd).now_or_never(), + Mode::Text => Self::deserialise_text(&mut reader, passwd).now_or_never(), } .ok_or_else(|| eyre::eyre!("Failed to complete {} read syncronously. A future returned `Poll::Pending`.", mode)) .with_note(note.clone())?