Skip to main content

SecretValue

Struct SecretValue 

Source
pub struct SecretValue(/* private fields */);
Expand description

A secret held as bytes and zeroized when it is dropped.

Debug and Display print ***, so the value does not end up in logs or panic messages. Clone makes a second buffer, and each copy is zeroized on its own drop. == takes time that depends on the lengths only, not on the bytes.

The value is read in two ways:

  • borrowing it with as_sensitive_* and ref_sensitive_value, which make no copy;
  • lending a copy to a closure with exposed_in_*, which makes sure the copy is zeroized once the closure is done with it.
use secret_vault_value::SecretValue;

let secret_value = SecretValue::from("my-password");
assert_eq!(format!("{secret_value:?}"), "***");
assert_eq!(secret_value.to_string(), "***");
assert_eq!(secret_value.as_sensitive_str(), "my-password");

Implementations§

Source§

impl SecretValue

Source

pub fn new(src: Vec<u8>) -> SecretValue

Takes ownership of src without copying it.

Source

pub fn ref_sensitive_value(&self) -> &Vec<u8> ⓘ

Borrows the secret bytes.

Source

pub fn ref_sensitive_value_mut(&mut self) -> &mut Vec<u8> ⓘ

Borrows the secret bytes mutably.

Be aware that growing the vector may reallocate it, and the old allocation is freed without being zeroized. Reserve the capacity up front if the value is built in place.

Source

pub fn sensitive_value_to_str(&self) -> Result<&str, Utf8Error>

Borrows the secret as a string slice.

§Errors

Returns Utf8Error if the bytes are not valid UTF-8.

use secret_vault_value::SecretValue;

assert!(SecretValue::from("my-password").sensitive_value_to_str().is_ok());
assert!(SecretValue::new(vec![0xff]).sensitive_value_to_str().is_err());
Source

pub fn secure_clear(&mut self)

Zeroizes the bytes and leaves the value empty.

use secret_vault_value::SecretValue;

let mut secret_value = SecretValue::from("my-password");
secret_value.secure_clear();
assert!(secret_value.as_sensitive_bytes().is_empty());
Source

pub fn as_sensitive_str(&self) -> &str

Borrows the secret as a string slice.

§Panics

Panics if the bytes are not valid UTF-8. Use sensitive_value_to_str for binary secrets.

Source

pub fn as_sensitive_bytes(&self) -> &[u8] ⓘ

Borrows the secret bytes as a slice.

Source

pub fn exposed_in_as_str<T, Z, FN>(&self, f: FN) -> T
where Z: Zeroize, FN: Fn(String) -> (T, Z),

Lends a String copy of the secret to f and returns the first item of its result.

f returns a pair (T, Z): T is the result, Z is whatever must be zeroized once f returns, usually the String it was given. A copy that f neither returns as Z nor zeroizes itself is not zeroized. exposed_in_as_zstr needs no such pair.

If f panics, the copy is freed without being zeroized. Use exposed_in_as_zstr, which zeroizes it on unwinding too.

§Panics

Panics if the bytes are not valid UTF-8.

use secret_vault_value::SecretValue;

let secret_value = SecretValue::from("my-password");
let length = secret_value.exposed_in_as_str(|password| (password.len(), password));
assert_eq!(length, 11);
Source

pub fn exposed_in_as_zstr<T, FN>(&self, f: FN) -> T
where FN: Fn(Zeroizing<String>) -> T,

Lends a Zeroizing<String> copy of the secret to f and returns its result.

The copy is zeroized when f drops it.

§Panics

Panics if the bytes are not valid UTF-8.

use secret_vault_value::SecretValue;

let secret_value = SecretValue::from("my-password");
let length = secret_value.exposed_in_as_zstr(|password| password.len());
assert_eq!(length, 11);
Source

pub fn exposed_in_as_vec<T, Z, FN>(&self, f: FN) -> T
where Z: Zeroize, FN: Fn(Vec<u8>) -> (T, Z),

Lends a Vec<u8> copy of the secret to f and returns the first item of its result.

The (T, Z) pair works as in exposed_in_as_str: Z is zeroized once f returns.

If f panics, the copy is freed without being zeroized. Use exposed_in_as_zvec, which zeroizes it on unwinding too.

use secret_vault_value::SecretValue;

let secret_value = SecretValue::new(vec![1, 2, 3]);
let sum = secret_value.exposed_in_as_vec(|bytes| (bytes.iter().sum::<u8>(), bytes));
assert_eq!(sum, 6);
Source

pub fn exposed_in_as_zvec<T, FN>(&self, f: FN) -> T
where FN: Fn(Zeroizing<Vec<u8>>) -> T,

Lends a Zeroizing<Vec<u8>> copy of the secret to f and returns its result.

The copy is zeroized when f drops it.

use secret_vault_value::SecretValue;

let secret_value = SecretValue::new(vec![1, 2, 3]);
let sum = secret_value.exposed_in_as_zvec(|bytes| bytes.iter().sum::<u8>());
assert_eq!(sum, 6);
Source

pub async fn exposed_in_as_str_async<T, Z, FN, FI>(&self, f: FN) -> T
where Z: Zeroize, FN: Fn(String) -> FI, FI: Future<Output = (T, Z)>,

Async form of exposed_in_as_str: Z is zeroized once the future returned by f completes.

If f or its future panics, or the future is dropped before it completes (a timeout, a losing select! branch, an aborted task), the copy is freed without being zeroized. Use exposed_in_as_zstr_async, which zeroizes it in those cases too.

§Panics

Panics if the bytes are not valid UTF-8.

use secret_vault_value::SecretValue;

async fn password_length(secret_value: &SecretValue) -> usize {
    secret_value
        .exposed_in_as_str_async(|password| async move { (password.len(), password) })
        .await
}
Source

pub async fn exposed_in_as_zstr_async<T, FN, FI>(&self, f: FN) -> T
where FN: Fn(Zeroizing<String>) -> FI, FI: Future<Output = T>,

Async form of exposed_in_as_zstr: the copy is zeroized when the future returned by f drops it.

§Panics

Panics if the bytes are not valid UTF-8.

use secret_vault_value::SecretValue;

async fn password_length(secret_value: &SecretValue) -> usize {
    secret_value
        .exposed_in_as_zstr_async(|password| async move { password.len() })
        .await
}
Source

pub async fn exposed_in_as_vec_async<T, Z, FN, FI>(&self, f: FN) -> T
where Z: Zeroize, FN: Fn(Vec<u8>) -> FI, FI: Future<Output = (T, Z)>,

Async form of exposed_in_as_vec: Z is zeroized once the future returned by f completes.

If f or its future panics, or the future is dropped before it completes (a timeout, a losing select! branch, an aborted task), the copy is freed without being zeroized. Use exposed_in_as_zvec_async, which zeroizes it in those cases too.

use secret_vault_value::SecretValue;

async fn key_length(secret_value: &SecretValue) -> usize {
    secret_value
        .exposed_in_as_vec_async(|key| async move { (key.len(), key) })
        .await
}
Source

pub async fn exposed_in_as_zvec_async<T, FN, FI>(&self, f: FN) -> T
where FN: Fn(Zeroizing<Vec<u8>>) -> FI, FI: Future<Output = T>,

Async form of exposed_in_as_zvec: the copy is zeroized when the future returned by f drops it.

use secret_vault_value::SecretValue;

async fn key_length(secret_value: &SecretValue) -> usize {
    secret_value
        .exposed_in_as_zvec_async(|key| async move { key.len() })
        .await
}
Source§

impl SecretValue

Source

pub fn expose_json_value_as<T>(&self) -> Result<T, Error>
where T: for<'de> Deserialize<'de> + for<'de> Zeroize,

Parses the secret as JSON into T.

The Zeroize bound lets the caller wipe the result, but the result is not zeroized automatically: call zeroize() on it, or wrap it in zeroize::Zeroizing, once it is no longer needed.

§Errors

Returns serde_json::Error if the secret is not valid JSON for T.

use secret_vault_value::SecretValue;
use serde::Deserialize;
use zeroize::{Zeroize, Zeroizing};

#[derive(Deserialize, Zeroize)]
struct Credentials {
    user: String,
    password: String,
}

let secret_value = SecretValue::from(r#"{"user":"admin","password":"my-password"}"#);
let credentials = Zeroizing::new(secret_value.expose_json_value_as::<Credentials>()?);
assert_eq!(credentials.user, "admin");

Trait Implementations§

Source§

impl Clone for SecretValue

Source§

fn clone(&self) -> SecretValue

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for SecretValue

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Default for SecretValue

Source§

fn default() -> SecretValue

Returns the “default value” for a type. Read more
Source§

impl<'de> Deserialize<'de> for SecretValue

Deserializes the secret from a string or from bytes.

Source§

fn deserialize<D>( deserializer: D, ) -> Result<SecretValue, <D as Deserializer<'de>>::Error>
where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl Display for SecretValue

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Drop for SecretValue

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more
Source§

impl Eq for SecretValue

Source§

impl From<&Zeroizing<String>> for SecretValue

Source§

fn from(str: &Zeroizing<String>) -> SecretValue

Converts to this type from the input type.
Source§

impl From<&Zeroizing<Vec<u8>>> for SecretValue

Source§

fn from(vec: &Zeroizing<Vec<u8>>) -> SecretValue

Converts to this type from the input type.
Source§

impl From<&mut String> for SecretValue

Copies the bytes and zeroizes the caller’s String, leaving it empty.

Source§

fn from(str: &mut String) -> SecretValue

Converts to this type from the input type.
Source§

impl From<&mut Vec<u8>> for SecretValue

Copies the bytes and zeroizes the caller’s Vec, leaving it empty.

Source§

fn from(vec: &mut Vec<u8>) -> SecretValue

Converts to this type from the input type.
Source§

impl From<&str> for SecretValue

Source§

fn from(str: &str) -> SecretValue

Converts to this type from the input type.
Source§

impl From<String> for SecretValue

Copies the bytes and zeroizes the source String.

Source§

fn from(str: String) -> SecretValue

Converts to this type from the input type.
Source§

impl From<Vec<u8>> for SecretValue

Source§

fn from(vec: Vec<u8>) -> SecretValue

Converts to this type from the input type.
Source§

impl Hash for SecretValue

Source§

fn hash<H>(&self, state: &mut H)
where H: Hasher,

Feeds this value into the given Hasher. Read more
1.3.0 · Source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where H: Hasher, Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
Source§

impl PartialEq for SecretValue

Source§

fn eq(&self, other: &SecretValue) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl Serialize for SecretValue

Serializes the secret as a string.

Fails if the bytes are not valid UTF-8.

Source§

fn serialize<S>( &self, serializer: S, ) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
where S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl Zeroize for SecretValue

Source§

fn zeroize(&mut self)

Zero out this object from memory using Rust intrinsics which ensure the zeroization operation is not “optimized away” by the compiler.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,

Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> FromRef<T> for T
where T: Clone,

Source§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoRequest<T> for T

Source§

fn into_request(self) -> Request<T>

Wrap the input message T in a tonic::Request
Source§

impl<L> LayerExt<L> for L

Source§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in Layered.
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more