Skip to content

Commit

Permalink
secrecy/zeroize: Upgrade to bytes v0.5
Browse files Browse the repository at this point in the history
- Removes the `bytes-preview` feature from `zeroize`
- Upgrades `secrecy` to use `bytes` v0.5

Now that `bytes` v0.5 is out, I've opened a PR to upstream the `Zeroize`
impl for `BytesMut`:

tokio-rs/bytes#335

Unfortunately it's no-longer possible to impl `Zeroize` for `Bytes` as
of `bytes` v0.5, as the `try_mut` method was dropped in this PR:

tokio-rs/bytes#298

I have brought this up on the first PR.

In the meantime, this vendors the previous `BytesMut` impl of `Zeroize`
into `secrecy`'s `SecretBytesMut` type, and drops `SecretBytes` as it's
no-longer possible to implement.
  • Loading branch information
tony-iqlusion committed Dec 2, 2019
1 parent 0c1a2fe commit bedfdef
Show file tree
Hide file tree
Showing 7 changed files with 30 additions and 116 deletions.
25 changes: 3 additions & 22 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions secrecy/Cargo.toml
Expand Up @@ -22,12 +22,12 @@ maintenance = { status = "passively-maintained" }
[dependencies]
serde = { version = "1", optional = true }
zeroize = { version = "1.0.0", path = "../zeroize", default-features = false }
bytes_crate = { package = "bytes", version = "0.4", features = ["serde"], optional = true }
bytes = { version = "0.5", optional = true }

[features]
default = ["alloc"]
alloc = ["zeroize/alloc"]
bytes = ["bytes_crate", "zeroize/bytes-preview"]
bytes-serde = ["bytes/serde", "serde"]

[package.metadata.docs.rs]
all-features = true
66 changes: 24 additions & 42 deletions secrecy/src/bytes.rs
@@ -1,78 +1,60 @@
//! Optional `Secret` wrapper type for the `bytes::BytesMut` crate.

use super::{CloneableSecret, DebugSecret, ExposeSecret, Secret};
use bytes_crate::{Bytes, BytesMut};
use super::ExposeSecret;
use bytes::BytesMut;
use core::fmt;
use zeroize::Zeroize;

#[cfg(feature = "serde")]
#[cfg(feature = "bytes-serde")]
use serde::de::{Deserialize, Deserializer};

/// Instance of `Bytes` protected by a type that impls the `ExposeSecret`
/// Instance of `BytesMut` protected by a type that impls the `ExposeSecret`
/// trait like `Secret<T>`.
///
/// Because of the nature of how the `Bytes` type works, it needs some special
/// care in order to have a proper zeroizing drop handler.
#[derive(Clone)]
pub struct SecretBytes(Option<Bytes>);
pub struct SecretBytesMut(BytesMut);

impl SecretBytes {
/// Wrap bytes in `SecretBytes`
pub fn new(bytes: impl Into<Bytes>) -> SecretBytes {
SecretBytes(Some(bytes.into()))
impl SecretBytesMut {
/// Wrap bytes in `SecretBytesMut`
pub fn new(bytes: impl Into<BytesMut>) -> SecretBytesMut {
SecretBytesMut(bytes.into())
}
}

impl ExposeSecret<Bytes> for SecretBytes {
fn expose_secret(&self) -> &Bytes {
self.0.as_ref().unwrap()
impl ExposeSecret<BytesMut> for SecretBytesMut {
fn expose_secret(&self) -> &BytesMut {
&self.0
}
}

impl fmt::Debug for SecretBytes {
impl fmt::Debug for SecretBytesMut {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "SecretBytes(...)")
write!(f, "SecretBytesMut([REDACTED])")
}
}

impl From<Bytes> for SecretBytes {
fn from(bytes: Bytes) -> SecretBytes {
SecretBytes::new(bytes)
impl From<BytesMut> for SecretBytesMut {
fn from(bytes: BytesMut) -> SecretBytesMut {
SecretBytesMut::new(bytes)
}
}

impl From<BytesMut> for SecretBytes {
fn from(bytes: BytesMut) -> SecretBytes {
SecretBytes::new(bytes)
}
}

impl Drop for SecretBytes {
impl Drop for SecretBytesMut {
fn drop(&mut self) {
// To zero the contents of `Bytes`, we have to take ownership of it
// and then attempt to convert it to a `BytesMut`. If that succeeds,
// we are holding the last reference to the inner byte buffer, which
// indicates its lifetime has ended and it's ready to be zeroed.
if let Some(bytes) = self.0.take() {
if let Ok(mut bytes_mut) = bytes.try_mut() {
bytes_mut.zeroize();
}
}
self.0.resize(self.0.capacity(), 0);
self.0.as_mut().zeroize();
debug_assert!(self.0.as_ref().iter().all(|b| *b == 0));
}
}

#[cfg(feature = "serde")]
impl<'de> Deserialize<'de> for SecretBytes {
#[cfg(feature = "bytes-serde")]
impl<'de> Deserialize<'de> for SecretBytesMut {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
Bytes::deserialize(deserializer).map(SecretBytes::new)
BytesMut::deserialize(deserializer).map(SecretBytesMut::new)
}
}

/// Alias for `Secret<BytesMut>`
pub type SecretBytesMut = Secret<BytesMut>;

impl DebugSecret for BytesMut {}
impl CloneableSecret for BytesMut {}
2 changes: 1 addition & 1 deletion secrecy/src/lib.rs
Expand Up @@ -22,7 +22,7 @@ mod vec;
pub use self::{boxed::SecretBox, string::SecretString, vec::SecretVec};

#[cfg(feature = "bytes")]
pub use self::bytes::{SecretBytes, SecretBytesMut};
pub use self::bytes::SecretBytesMut;

use core::fmt::{self, Debug};
#[cfg(feature = "serde")]
Expand Down
2 changes: 0 additions & 2 deletions zeroize/Cargo.toml
Expand Up @@ -22,12 +22,10 @@ maintenance = { status = "passively-maintained" }

[dependencies]
zeroize_derive = { version = "1.0.0", path = "../zeroize_derive", optional = true }
bytes = { version = "0.4", optional = true }

[features]
default = ["alloc"]
alloc = []
bytes-preview = ["bytes"]

[package.metadata.docs.rs]
all-features = true
31 changes: 0 additions & 31 deletions zeroize/src/bytes.rs

This file was deleted.

16 changes: 0 additions & 16 deletions zeroize/src/lib.rs
Expand Up @@ -112,19 +112,6 @@
//! }
//! ```
//!
//! ## `bytes-preview` feature: `Zeroize` support for `BytesMut`
//!
//! This crate contains an impl of `Zeroize` for the `BytesMut` type from the
//! `bytes` crate.
//!
//! As `bytes` is not yet 1.0, this is a "preview" feature which we do not
//! include in SemVer guarantees around the `zeroize` crate. Ideally, we can
//! upstream the implementation and remove the feature entirely.
//!
//! Whenever we make any changes to how the `bytes-preview` feature works,
//! such as upgrading the `bytes` crate version or removing it after
//! successfully upstreaming, it will be done with a minor version bump.
//!
//! ## What guarantees does this crate provide?
//!
//! This crate guarantees the following:
Expand Down Expand Up @@ -221,9 +208,6 @@
#[cfg_attr(test, macro_use)]
extern crate alloc;

#[cfg(feature = "bytes-preview")]
mod bytes;

#[cfg(feature = "zeroize_derive")]
pub use zeroize_derive::Zeroize;

Expand Down

0 comments on commit bedfdef

Please sign in to comment.