#![cfg(feature = "ztier")]
#[cfg(feature = "keyless")]
use crate::constants::HARDCODED_SECRET_BYTES;
use crate::{format::IntoFormat, Error};
use super::zdec_auto;
use super::zsecret::ZSecret;
pub struct Omnibz {
zsecret: ZSecret,
}
impl Omnibz {
pub fn new(secret_b64: &str) -> Result<Self, Error> {
Ok(Self {
zsecret: ZSecret::from_base64(secret_b64)?,
})
}
#[cfg(feature = "keyless")]
pub fn new_keyless() -> Result<Self, Error> {
Ok(Self {
zsecret: ZSecret::from_bytes(&HARDCODED_SECRET_BYTES)?,
})
}
#[inline]
pub fn enc(&self, plaintext: &str, format: impl IntoFormat) -> Result<String, Error> {
let format = format.into_format()?;
validate_ztier_scheme(format.scheme())?;
crate::ztier::enc_to_format_ztier(plaintext, format, self.zsecret.master_secret())
}
#[inline]
pub fn dec(&self, obtext: &str, format: impl IntoFormat) -> Result<String, Error> {
let format = format.into_format()?;
validate_ztier_scheme(format.scheme())?;
crate::ztier::dec_from_format_ztier(obtext, format, self.zsecret.master_secret())
}
pub fn autodec(&self, obtext: &str) -> Result<String, Error> {
zdec_auto::dec_any_format_ztier(&self.zsecret, obtext)
}
pub fn secret(&self) -> String {
self.zsecret.secret_base64()
}
#[cfg(feature = "hex-keys")]
pub fn secret_hex(&self) -> String {
self.zsecret.secret_hex()
}
#[cfg(feature = "bytes-keys")]
pub fn secret_bytes(&self) -> &[u8; 32] {
self.zsecret.secret_bytes()
}
#[cfg(feature = "hex-keys")]
pub fn from_secret_hex(secret_hex: &str) -> Result<Self, Error> {
Ok(Self {
zsecret: ZSecret::from_hex(secret_hex)?,
})
}
#[cfg(feature = "bytes-keys")]
pub fn from_bytes(secret_bytes: &[u8; 32]) -> Result<Self, Error> {
Ok(Self {
zsecret: ZSecret::from_bytes(secret_bytes)?,
})
}
}
fn validate_ztier_scheme(scheme: crate::Scheme) -> Result<(), Error> {
match scheme {
#[cfg(feature = "zrbcx")]
crate::Scheme::Zrbcx => Ok(()),
#[cfg(feature = "zmock")]
crate::Scheme::Zmock1 => Ok(()),
#[cfg(feature = "legacy")]
crate::Scheme::Legacy => Ok(()),
_ => Err(Error::InvalidScheme),
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[cfg(feature = "zrbcx")]
fn test_omnibz_basic() {
let secret = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"; let omz = Omnibz::new(secret).unwrap();
let plaintext = "hello world";
let ot = omz.enc(plaintext, "zrbcx.b64").unwrap();
let pt2 = omz.dec(&ot, "zrbcx.b64").unwrap();
assert_eq!(pt2, plaintext);
}
#[test]
#[cfg(feature = "zrbcx")]
fn test_omnibz_autodec() {
let secret = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
let omz = Omnibz::new(secret).unwrap();
let plaintext = "test data";
let ot = omz.enc(plaintext, "zrbcx.c32").unwrap();
let pt2 = omz.autodec(&ot).unwrap();
assert_eq!(pt2, plaintext);
}
#[test]
#[cfg(all(feature = "zrbcx", feature = "zmock"))]
fn test_omnibz_multiple_formats() {
let secret = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
let omz = Omnibz::new(secret).unwrap();
let plaintext = "multi format test";
let ot1 = omz.enc(plaintext, "zrbcx.b64").unwrap();
let ot2 = omz.enc(plaintext, "zmock1.c32").unwrap();
let pt1 = omz.autodec(&ot1).unwrap();
let pt2 = omz.autodec(&ot2).unwrap();
assert_eq!(pt1, plaintext);
assert_eq!(pt2, plaintext);
}
#[test]
#[cfg(feature = "zrbcx")]
fn test_omnibz_secret_methods() {
let secret = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
let omz = Omnibz::new(secret).unwrap();
let retrieved = omz.secret();
assert_eq!(retrieved, secret);
assert_eq!(retrieved.len(), 43);
#[cfg(feature = "hex-keys")]
{
let secret_hex = omz.secret_hex();
assert_eq!(secret_hex.len(), 64);
}
#[cfg(feature = "bytes-keys")]
{
let secret_bytes = omz.secret_bytes();
assert_eq!(secret_bytes.len(), 32);
}
}
#[test]
#[cfg(all(feature = "zrbcx", feature = "keyless"))]
fn test_omnibz_keyless() {
let omz = Omnibz::new_keyless().unwrap();
let plaintext = "keyless test";
let ot = omz.enc(plaintext, "zrbcx.b64").unwrap();
let pt2 = omz.autodec(&ot).unwrap();
assert_eq!(pt2, plaintext);
}
#[test]
#[cfg(all(feature = "zrbcx", feature = "hex-keys"))]
fn test_omnibz_from_hex() {
let secret_hex = "0".repeat(64);
let omz = Omnibz::from_secret_hex(&secret_hex).unwrap();
let plaintext = "hex secret test";
let ot = omz.enc(plaintext, "zrbcx.b64").unwrap();
let pt2 = omz.autodec(&ot).unwrap();
assert_eq!(pt2, plaintext);
}
#[test]
#[cfg(all(feature = "zrbcx", feature = "bytes-keys"))]
fn test_omnibz_from_bytes() {
let secret_bytes = [0u8; 32];
let omz = Omnibz::from_bytes(&secret_bytes).unwrap();
let plaintext = "bytes secret test";
let ot = omz.enc(plaintext, "zrbcx.b64").unwrap();
let pt2 = omz.autodec(&ot).unwrap();
assert_eq!(pt2, plaintext);
}
#[test]
#[cfg(feature = "zrbcx")]
fn test_omnibz_rejects_non_ztier_scheme() {
let secret = "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";
let omz = Omnibz::new(secret).unwrap();
#[cfg(feature = "aasv")]
{
let result = omz.enc("test", "aasv.b64");
assert!(result.is_err());
}
}
}