Skip to main content

co_storage/crypto/
secret.rs

1// SPDX-License-Identifier: AGPL-3.0-only
2// Copyright (C) 2026 1io BRANDGUARDIAN GmbH
3
4use aead::rand_core::RngCore;
5use blake3::derive_key;
6use chacha20poly1305::aead::OsRng;
7use std::fmt::Display;
8
9/// Stores a secrent and ensures it will only be showen using the divulge method.
10/// Display and debug traits are implemented and will only show masked keys.
11#[derive(Clone, Debug)]
12pub struct Secret(co_primitives::Secret);
13impl Secret {
14	/// Create secret from vec.
15	pub fn new(secret: Vec<u8>) -> Self {
16		Self(co_primitives::Secret::new(secret))
17	}
18
19	/// Generate random secret of given size.
20	pub fn generate(size: usize) -> Self {
21		let mut secret: Vec<u8> = vec![0; size];
22		OsRng.fill_bytes(secret.as_mut_slice());
23		Self::new(secret)
24	}
25
26	/// Derive secret.
27	pub fn derive_serect(&self, context: &str) -> Secret {
28		Secret::new(derive_key(context, self.divulge()).to_vec())
29	}
30
31	/// Derive secret with salt.
32	pub fn derive_serect_with_salt(&self, context: &str, salt: &Vec<u8>) -> Secret {
33		// append the salt
34		let salted_secret = {
35			let mut with_salt = self.divulge().to_vec();
36			with_salt.extend_from_slice(salt.as_slice());
37			Secret::new(with_salt)
38		};
39
40		// derive
41		salted_secret.derive_serect(context)
42	}
43
44	/// Divulge the secret.
45	pub fn divulge(&self) -> &[u8] {
46		self.0.divulge()
47	}
48}
49impl Display for Secret {
50	fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
51		write!(f, "{}", self.0)
52	}
53}
54impl From<Secret> for co_primitives::Secret {
55	fn from(val: Secret) -> Self {
56		val.0
57	}
58}
59impl From<co_primitives::Secret> for Secret {
60	fn from(value: co_primitives::Secret) -> Self {
61		Self(value)
62	}
63}