| // Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. |
| // SPDX-License-Identifier: Apache-2.0 OR ISC |
| |
| //! This module exposes a buffer type used in crate APIs returning private keys and other "private" |
| //! contents. |
| |
| #![allow(clippy::module_name_repetitions)] |
| |
| use alloc::borrow::Cow; |
| use core::fmt; |
| use core::marker::PhantomData; |
| |
| use zeroize::Zeroize; |
| |
| /// This is a buffer type for some data exposed by various APIs in this crate. |
| /// |
| /// `T` acts as a discriminant between different kinds of data. |
| /// |
| /// The buffer will be zeroed on drop if it is owned. |
| pub struct Buffer<'a, T>(Cow<'a, [u8]>, PhantomData<T>); |
| |
| impl<T> Drop for Buffer<'_, T> { |
| fn drop(&mut self) { |
| if let Cow::Owned(b) = &mut self.0 { |
| b.zeroize(); |
| } |
| } |
| } |
| |
| impl<'a, T> Buffer<'a, T> { |
| pub(crate) fn new(owned: Vec<u8>) -> Buffer<'a, T> { |
| Buffer(Cow::Owned(owned), PhantomData) |
| } |
| |
| pub(crate) fn take_from_slice(slice: &mut [u8]) -> Buffer<'a, T> { |
| let owned = slice.to_vec(); |
| slice.zeroize(); |
| Buffer(Cow::Owned(owned), PhantomData) |
| } |
| } |
| |
| impl<T> fmt::Debug for Buffer<'_, T> { |
| fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { |
| f.write_str("Buffer(...)") |
| } |
| } |
| |
| impl<T> AsRef<[u8]> for Buffer<'_, T> { |
| #[inline] |
| fn as_ref(&self) -> &[u8] { |
| self.0.as_ref() |
| } |
| } |
| |
| #[cfg(test)] |
| mod tests { |
| use super::*; |
| |
| #[test] |
| fn test_new() { |
| let buffer: Buffer<u8> = Buffer::new(vec![1, 2, 3]); |
| assert_eq!(buffer.as_ref(), &[1, 2, 3]); |
| } |
| |
| #[test] |
| fn test_take_from_slice() { |
| let mut slice = [1, 2, 3]; |
| let buffer: Buffer<u8> = Buffer::take_from_slice(&mut slice); |
| assert_eq!(buffer.as_ref(), &[1, 2, 3]); |
| assert_eq!(slice, [0, 0, 0]); |
| } |
| } |