use crate::errors::Error; use crate::version::private::Version; use alloc::vec::Vec; use core::fmt::Debug; use core::marker::PhantomData; /// A type `T` that can be generated for a given version `V`. pub trait Generate { /// Generate `T`. fn generate() -> Result; } #[derive(Clone)] /// A symmetric key used for `.local` tokens, given a version `V`. pub struct SymmetricKey { pub(crate) bytes: Vec, pub(crate) phantom: PhantomData, } impl SymmetricKey { /// Create a `SymmetricKey` from `bytes`. pub fn from(bytes: &[u8]) -> Result { V::validate_local_key(bytes)?; Ok(Self { bytes: bytes.to_vec(), phantom: PhantomData, }) } /// Return this as a byte-slice. pub fn as_bytes(&self) -> &[u8] { self.bytes.as_slice() } } impl Drop for SymmetricKey { fn drop(&mut self) { use zeroize::Zeroize; self.bytes.iter_mut().zeroize(); } } impl Debug for SymmetricKey { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(f, "SymmetricKey {{***OMITTED***}}") } } impl PartialEq> for SymmetricKey { fn eq(&self, other: &SymmetricKey) -> bool { use subtle::ConstantTimeEq; self.as_bytes().ct_eq(other.as_bytes()).into() } } #[derive(Clone)] /// An asymmetric secret key used for `.public` tokens, given a version `V`. /// /// In case of Ed25519, which is used in V2 and V4, this is the seed concatenated with the public key. pub struct AsymmetricSecretKey { pub(crate) bytes: Vec, pub(crate) phantom: PhantomData, } impl AsymmetricSecretKey { /// Create a `AsymmetricSecretKey` from `bytes`. /// /// __PANIC__: If the version is V2 or V4, a panic will occur if an all-zero /// secret seed is used. pub fn from(bytes: &[u8]) -> Result { V::validate_secret_key(bytes)?; Ok(Self { bytes: bytes.to_vec(), phantom: PhantomData, }) } /// Return this as a byte-slice. pub fn as_bytes(&self) -> &[u8] { self.bytes.as_slice() } } impl Drop for AsymmetricSecretKey { fn drop(&mut self) { use zeroize::Zeroize; self.bytes.iter_mut().zeroize(); } } impl Debug for AsymmetricSecretKey { fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { write!(f, "AsymmetricSecretKey {{***OMITTED***}}") } } impl PartialEq> for AsymmetricSecretKey { fn eq(&self, other: &AsymmetricSecretKey) -> bool { use subtle::ConstantTimeEq; self.as_bytes().ct_eq(other.as_bytes()).into() } } #[derive(Debug, Clone)] /// An asymmetric public key used for `.public` tokens, given a version `V`. pub struct AsymmetricPublicKey { pub(crate) bytes: Vec, pub(crate) phantom: PhantomData, } impl AsymmetricPublicKey { /// Create a `AsymmetricPublicKey` from `bytes`. pub fn from(bytes: &[u8]) -> Result { V::validate_public_key(bytes)?; Ok(Self { bytes: bytes.to_vec(), phantom: PhantomData, }) } /// Return this as a byte-slice. pub fn as_bytes(&self) -> &[u8] { self.bytes.as_slice() } } impl PartialEq> for AsymmetricPublicKey { fn eq(&self, other: &AsymmetricPublicKey) -> bool { use subtle::ConstantTimeEq; self.as_bytes().ct_eq(other.as_bytes()).into() } } #[derive(Debug, Clone)] /// A keypair of an [`AsymmetricSecretKey`] and its corresponding [`AsymmetricPublicKey`]. pub struct AsymmetricKeyPair { /// The [`AsymmetricSecretKey`]. pub public: AsymmetricPublicKey, /// The [`AsymmetricPublicKey`]. pub secret: AsymmetricSecretKey, }