From 590fcedf819526da1b644fc81ee188e69225045d Mon Sep 17 00:00:00 2001 From: Avril Date: Wed, 9 Sep 2020 04:23:42 +0100 Subject: [PATCH] serde --- Cargo.toml | 7 ++++++- src/bytes.rs | 21 +++++++++++++++++++-- src/lib.rs | 5 +++++ src/rsa/containers.rs | 2 +- src/rsa/private.rs | 6 +++--- src/rsa/public.rs | 6 +++--- src/sha256.rs | 1 + 7 files changed, 38 insertions(+), 10 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9e2c5d4..6913748 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cryptohelpers" -version = "0.1.1" +version = "1.1.0" license= "MIT" description = "Collection of helpers and simplifying functions for cryptography things" authors = ["Avril "] @@ -18,8 +18,11 @@ crc = {version = "1.8", optional = true } hex-literal = {version = "0.3", optional = true } libc = "0.2" tokio = {version = "0.2", features=["io-util"], optional=true} +serde_derive = {version = "1.0", optional = true} +serde = {version = "1.0", optional = true} [features] +#default = ["full", "async", "serialise"] async = ["tokio"] # Actual things @@ -31,6 +34,8 @@ full = [ "rsa" ] +serialise = ["serde_derive"] + sha256 = ["sha2"] password = ["sha256", "pbkdf2", "hex-literal", "hmac", "getrandom"] aes = ["openssl", "getrandom"] diff --git a/src/bytes.rs b/src/bytes.rs index 4e42840..e51203d 100644 --- a/src/bytes.rs +++ b/src/bytes.rs @@ -51,9 +51,26 @@ pub fn refer_mut(value: &mut T) -> &mut [u8] /// /// # Notes /// This function omits bounds checks in production builds -pub fn derefer(bytes: &[u8]) -> &T +pub unsafe fn derefer_unchecked(bytes: &[u8]) -> &T { #[cfg(debug_assertions)] assert!(bytes.len() >= mem::size_of::(), "not enough bytes "); + &*(&bytes[0] as *const u8 as *const T) +} + +/// Get a mutable reference to a type from its bytes +/// +/// # Notes +/// This function omits bounds checks in production builds +pub unsafe fn derefer_unchecked_mut(bytes: &mut [u8]) -> &mut T +{ + #[cfg(debug_assertions)] assert!(bytes.len() >= mem::size_of::(), "not enough bytes "); + &mut *(&mut bytes[0] as *mut u8 as *mut T) +} + +/// Get a type from its bytes +pub fn derefer(bytes: &[u8]) -> &T +{ + assert!(bytes.len() >= mem::size_of::(), "not enough bytes "); unsafe { &*(&bytes[0] as *const u8 as *const T) } @@ -65,7 +82,7 @@ pub fn derefer(bytes: &[u8]) -> &T /// This function omits bounds checks in production builds pub fn derefer_mut(bytes: &mut [u8]) -> &mut T { - #[cfg(debug_assertions)] assert!(bytes.len() >= mem::size_of::(), "not enough bytes "); + assert!(bytes.len() >= mem::size_of::(), "not enough bytes "); unsafe { &mut *(&mut bytes[0] as *mut u8 as *mut T) } diff --git a/src/lib.rs b/src/lib.rs index cede6a3..02c2281 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,6 +24,11 @@ mod bytes; #[allow(unused_imports)] mod error; +#[cfg(feature="serde")] +use serde_derive::{ + Serialize, Deserialize, +}; + // Actual things #[cfg(feature="sha256")] diff --git a/src/rsa/containers.rs b/src/rsa/containers.rs index 1f65c75..2056182 100644 --- a/src/rsa/containers.rs +++ b/src/rsa/containers.rs @@ -26,7 +26,7 @@ pub trait PublicKey fn get_pkey_pub(&self) -> Result>, Self::Error>; /// Get or create an `Rsa` from this public key if possible - fn get_rsa_pub(&self) -> Result>>, Self::Error> + #[inline] fn get_rsa_pub(&self) -> Result>>, Self::Error> { Ok(self.get_pkey_pub()?.rsa().ok().map(|x| Cow::Owned(x))) } diff --git a/src/rsa/private.rs b/src/rsa/private.rs index c3b0aea..a7ac3e4 100644 --- a/src/rsa/private.rs +++ b/src/rsa/private.rs @@ -188,7 +188,7 @@ impl RsaPrivateKey return Err(Error::Binary(BinaryErrorKind::Length{expected: Some(OFF_SIZE), got: Some(bytes.len())})); } - let offset: &PrivateOffsetGroup = bytes::derefer(&bytes[..OFF_SIZE]); + let offset: &PrivateOffsetGroup = unsafe{bytes::derefer_unchecked(&bytes[..OFF_SIZE])}; let bytes = &bytes[OFF_SIZE..]; let sz = offset.body_len(); @@ -250,7 +250,7 @@ impl RsaPrivateKey if buffer.len() != from.read_exact(&mut buffer[..]).await? { return Err(io::Error::new(io::ErrorKind::UnexpectedEof, "couldn't read offsets")); } else { - *bytes::derefer(&buffer[..]) + *unsafe{bytes::derefer_unchecked(&buffer[..])} } }; @@ -275,7 +275,7 @@ impl RsaPrivateKey let mut buffer = [0u8; size_of::()]; from.read_exact(&mut buffer[..])?; - *bytes::derefer(&buffer[..]) + *unsafe{bytes::derefer_unchecked(&buffer[..])} }; let mut data = vec![0u8; offset.body_len()]; diff --git a/src/rsa/public.rs b/src/rsa/public.rs index 59084b9..8d07a8d 100644 --- a/src/rsa/public.rs +++ b/src/rsa/public.rs @@ -129,7 +129,7 @@ impl RsaPublicKey return Err(Error::Binary(BinaryErrorKind::Length{expected: Some(size_of::()), got: Some(bytes.len())})); } - let offset: &PublicOffsetGroup = bytes::derefer(&bytes[..size_of::()]); + let offset: &PublicOffsetGroup = unsafe {bytes::derefer_unchecked(&bytes[..size_of::()])}; let bytes = &bytes[size_of::()..]; let sz = offset.body_len(); @@ -190,7 +190,7 @@ impl RsaPublicKey if buffer.len() != from.read_exact(&mut buffer[..]).await? { return Err(io::Error::new(io::ErrorKind::UnexpectedEof, "couldn't read offsets")); } else { - *bytes::derefer(&buffer[..]) + *unsafe{bytes::derefer_unchecked(&buffer[..])} } }; @@ -215,7 +215,7 @@ impl RsaPublicKey let mut buffer = [0u8; size_of::()]; from.read_exact(&mut buffer[..])?; - *bytes::derefer(&buffer[..]) + *unsafe{bytes::derefer_unchecked(&buffer[..])} }; let mut data = vec![0u8; offset.body_len()]; diff --git a/src/sha256.rs b/src/sha256.rs index ea27ae8..a05a934 100644 --- a/src/sha256.rs +++ b/src/sha256.rs @@ -20,6 +20,7 @@ const SIZE: usize = consts::SHA256_SIZE; /// Represents a SHA256 hash #[derive(Clone, Copy, Default, PartialEq, Eq, Hash, Debug)] #[repr(C, packed)] +#[cfg_attr(feature="serde", derive(Serialize,Deserialize))] pub struct Sha256Hash { hash: [u8; SIZE],