#[cfg(feature = "alloc")]
use alloc::vec::Vec;
use zeroize::{
Zeroize,
ZeroizeOnDrop,
};
#[derive(Zeroize, ZeroizeOnDrop)]
pub struct SecureKey {
data: Vec<u8>,
}
impl SecureKey {
pub fn new(data: Vec<u8>) -> Self {
Self { data }
}
pub fn with_capacity(capacity: usize) -> Self {
Self {
data: Vec::with_capacity(capacity),
}
}
pub fn as_slice(&self) -> &[u8] {
&self.data
}
pub fn as_mut_slice(&mut self) -> &mut [u8] {
&mut self.data
}
pub fn len(&self) -> usize {
self.data.len()
}
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
pub fn resize(&mut self, new_len: usize, value: u8) {
self.data.resize(new_len, value);
}
pub fn extend_from_slice(&mut self, other: &[u8]) {
self.data.extend_from_slice(other);
}
pub fn clone(&self) -> Self {
Self {
data: self.data.clone(),
}
}
}
impl From<Vec<u8>> for SecureKey {
fn from(data: Vec<u8>) -> Self {
Self::new(data)
}
}
impl From<&[u8]> for SecureKey {
fn from(data: &[u8]) -> Self {
Self::new(data.to_vec())
}
}
#[derive(Zeroize, ZeroizeOnDrop)]
pub struct SecureNonce {
data: Vec<u8>,
}
impl SecureNonce {
pub fn new(data: Vec<u8>) -> Self {
Self { data }
}
pub fn with_capacity(capacity: usize) -> Self {
Self {
data: Vec::with_capacity(capacity),
}
}
pub fn as_slice(&self) -> &[u8] {
&self.data
}
pub fn as_mut_slice(&mut self) -> &mut [u8] {
&mut self.data
}
pub fn len(&self) -> usize {
self.data.len()
}
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
pub fn resize(&mut self, new_len: usize, value: u8) {
self.data.resize(new_len, value);
}
pub fn clone(&self) -> Self {
Self {
data: self.data.clone(),
}
}
}
impl From<Vec<u8>> for SecureNonce {
fn from(data: Vec<u8>) -> Self {
Self::new(data)
}
}
impl From<&[u8]> for SecureNonce {
fn from(data: &[u8]) -> Self {
Self::new(data.to_vec())
}
}
#[derive(Zeroize, ZeroizeOnDrop)]
pub struct SecureBuffer {
data: Vec<u8>,
}
impl SecureBuffer {
pub fn new() -> Self {
Self { data: Vec::new() }
}
pub fn with_capacity(capacity: usize) -> Self {
Self {
data: Vec::with_capacity(capacity),
}
}
pub fn as_slice(&self) -> &[u8] {
&self.data
}
pub fn as_mut_slice(&mut self) -> &mut [u8] {
&mut self.data
}
pub fn len(&self) -> usize {
self.data.len()
}
pub fn is_empty(&self) -> bool {
self.data.is_empty()
}
pub fn clear(&mut self) {
self.data.clear();
}
pub fn push(&mut self, byte: u8) {
self.data.push(byte);
}
pub fn extend_from_slice(&mut self, other: &[u8]) {
self.data.extend_from_slice(other);
}
pub fn resize(&mut self, new_len: usize, value: u8) {
self.data.resize(new_len, value);
}
}
impl Default for SecureBuffer {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use alloc::vec;
use super::*;
#[test]
fn test_secure_key() {
let key_data = vec![1u8, 2u8, 3u8, 4u8];
let mut key = SecureKey::new(key_data.clone());
assert_eq!(key.as_slice(), &key_data);
assert_eq!(key.len(), 4);
assert!(!key.is_empty());
key.resize(6, 0);
assert_eq!(key.len(), 6);
assert_eq!(key.as_slice(), &[1u8, 2u8, 3u8, 4u8, 0u8, 0u8]);
}
#[test]
fn test_secure_nonce() {
let nonce_data = vec![5u8, 6u8, 7u8, 8u8];
let nonce = SecureNonce::new(nonce_data.clone());
assert_eq!(nonce.as_slice(), &nonce_data);
assert_eq!(nonce.len(), 4);
assert!(!nonce.is_empty());
}
#[test]
fn test_secure_buffer() {
let mut buffer = SecureBuffer::new();
assert!(buffer.is_empty());
buffer.push(1);
buffer.push(2);
assert_eq!(buffer.len(), 2);
assert_eq!(buffer.as_slice(), &[1u8, 2u8]);
buffer.extend_from_slice(&[3u8, 4u8]);
assert_eq!(buffer.as_slice(), &[1u8, 2u8, 3u8, 4u8]);
buffer.clear();
assert!(buffer.is_empty());
}
}