// file: crates/ksp-wallet-lib/src/password.rs // version: 3 /// Owned VIEW password material. /// /// The value is never exposed through `Debug` or `Display`, is intentionally non-`Clone`, and is zeroized on drop. Consumers should move an existing /// `String` into this type instead of keeping unnecessary clear-text copies. /// /// ```compile_fail /// let password = ksp_wallet_lib::ViewPassword::new(std::string::String::from("test-only")); /// let duplicated = password.clone(); /// let _ = duplicated; /// ``` pub struct ViewPassword { value: std::string::String, } impl ViewPassword { /// Takes ownership of VIEW password material. #[must_use] pub fn new(value: std::string::String) -> Self { return Self { value }; } /// Borrows exact UTF-8 password bytes inside Wallet cryptographic operations. pub(crate) fn as_bytes(&self) -> &[u8] { return self.value.as_bytes(); } } impl std::fmt::Debug for ViewPassword { fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { return formatter.write_str("ViewPassword()"); } } impl std::ops::Drop for ViewPassword { fn drop(&mut self) { zeroize::Zeroize::zeroize(&mut self.value); } } /// Owned OWNER password material. /// /// The value is never exposed through `Debug` or `Display`, is intentionally non-`Clone`, and is zeroized on drop. Consumers should move an existing /// `String` into this type instead of keeping unnecessary clear-text copies. /// /// ```compile_fail /// let password = ksp_wallet_lib::OwnerPassword::new(std::string::String::from("test-only")); /// let duplicated = password.clone(); /// let _ = duplicated; /// ``` pub struct OwnerPassword { value: std::string::String, } impl OwnerPassword { /// Takes ownership of OWNER password material. #[must_use] pub fn new(value: std::string::String) -> Self { return Self { value }; } /// Borrows exact UTF-8 password bytes inside Wallet cryptographic operations. pub(crate) fn as_bytes(&self) -> &[u8] { return self.value.as_bytes(); } /// Creates one short-lived crate-internal duplicate for authenticated format migration while keeping the public type non-`Clone`. pub(crate) fn duplicate_for_internal_use(&self) -> Self { return Self::new(self.value.clone()); } } impl std::fmt::Debug for OwnerPassword { fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { return formatter.write_str("OwnerPassword()"); } } impl std::ops::Drop for OwnerPassword { fn drop(&mut self) { zeroize::Zeroize::zeroize(&mut self.value); } } #[cfg(test)] #[path = "../unit_tests/password.rs"] mod tests;