// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // Copyright by contributors to this project. // SPDX-License-Identifier: (Apache-2.0 OR MIT) use crate::error::IntoAnyError; #[cfg(mls_build_async)] use alloc::boxed::Box; use alloc::vec::Vec; use core::{ fmt::{self, Debug}, ops::Deref, }; use mls_rs_codec::{MlsDecode, MlsEncode, MlsSize}; use zeroize::Zeroizing; #[derive(Clone, PartialEq, Eq, MlsSize, MlsEncode, MlsDecode)] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] /// Wrapper type that holds a pre-shared key value and zeroizes on drop. pub struct PreSharedKey( #[mls_codec(with = "mls_rs_codec::byte_vec")] #[cfg_attr(feature = "serde", serde(with = "crate::zeroizing_serde"))] Zeroizing>, ); impl Debug for PreSharedKey { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { crate::debug::pretty_bytes(&self.0) .named("PreSharedKey") .fmt(f) } } impl PreSharedKey { /// Create a new PreSharedKey. pub fn new(data: Vec) -> Self { PreSharedKey(Zeroizing::new(data)) } /// Raw byte value. pub fn raw_value(&self) -> &[u8] { &self.0 } } impl From> for PreSharedKey { fn from(bytes: Vec) -> Self { Self::new(bytes) } } impl From>> for PreSharedKey { fn from(bytes: Zeroizing>) -> Self { Self(bytes) } } impl AsRef<[u8]> for PreSharedKey { fn as_ref(&self) -> &[u8] { self.raw_value() } } impl Deref for PreSharedKey { type Target = [u8]; fn deref(&self) -> &Self::Target { self.raw_value() } } #[derive(Clone, Eq, Hash, Ord, PartialOrd, PartialEq, MlsSize, MlsEncode, MlsDecode)] #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr( all(feature = "ffi", not(test)), safer_ffi_gen::ffi_type(clone, opaque) )] #[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))] /// An external pre-shared key identifier. pub struct ExternalPskId( #[mls_codec(with = "mls_rs_codec::byte_vec")] #[cfg_attr(feature = "serde", serde(with = "crate::vec_serde"))] Vec, ); impl Debug for ExternalPskId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { crate::debug::pretty_bytes(&self.0) .named("ExternalPskId") .fmt(f) } } #[cfg_attr(all(feature = "ffi", not(test)), safer_ffi_gen::safer_ffi_gen)] impl ExternalPskId { pub fn new(id_data: Vec) -> Self { Self(id_data) } } impl AsRef<[u8]> for ExternalPskId { fn as_ref(&self) -> &[u8] { &self.0 } } impl Deref for ExternalPskId { type Target = [u8]; fn deref(&self) -> &Self::Target { &self.0 } } impl From> for ExternalPskId { fn from(value: Vec) -> Self { ExternalPskId(value) } } /// Storage trait to maintain a set of pre-shared key values. #[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)] #[cfg_attr(mls_build_async, maybe_async::must_be_async)] pub trait PreSharedKeyStorage: Send + Sync { /// Error type that the underlying storage mechanism returns on internal /// failure. type Error: IntoAnyError; /// Get a pre-shared key by [`ExternalPskId`](ExternalPskId). /// /// `None` should be returned if a pre-shared key can not be found for `id`. async fn get(&self, id: &ExternalPskId) -> Result, Self::Error>; /// Determines if a PSK is located within the store async fn contains(&self, id: &ExternalPskId) -> Result { self.get(id).await.map(|key| key.is_some()) } }