use serde::{Deserialize, Serialize};
use zeroize::ZeroizeOnDrop;
#[derive(ZeroizeOnDrop)]
pub struct SessionKey(Box<[u8; 32]>);
impl SessionKey {
pub fn from_bytes(bytes: [u8; 32]) -> Self {
Self(Box::new(bytes))
}
pub fn as_bytes(&self) -> &[u8; 32] {
&self.0
}
}
#[non_exhaustive]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Entry {
#[serde(with = "base64_serde")]
pub fake: Vec<u8>,
#[serde(with = "base64_serde")]
pub(crate) nonce: Vec<u8>,
#[serde(with = "base64_serde")]
pub(crate) ciphertext: Vec<u8>,
}
impl Entry {
#[doc(hidden)]
pub fn new_for_testing(fake: Vec<u8>, nonce: Vec<u8>, ciphertext: Vec<u8>) -> Self {
Self {
fake,
nonce,
ciphertext,
}
}
#[doc(hidden)]
pub fn flip_last_ciphertext_byte_for_testing(&mut self) {
if let Some(b) = self.ciphertext.last_mut() {
*b ^= 0xFF;
}
}
pub fn serialize_entries(entries: &[Entry]) -> Result<Vec<u8>, serde_json::Error> {
serde_json::to_vec_pretty(entries)
}
pub fn deserialize_entries(data: &[u8]) -> Result<Vec<Entry>, serde_json::Error> {
serde_json::from_slice(data)
}
}
#[non_exhaustive]
pub struct SwapResult {
pub payload: Vec<u8>,
pub entries: Vec<Entry>,
pub session_key: SessionKey,
}
#[derive(Debug, thiserror::Error)]
#[non_exhaustive]
pub enum SwapError {
#[error("encryption failed: {msg}")]
Crypto {
msg: String,
},
#[error("fake generation failed: {msg}")]
Fake {
msg: String,
},
}
impl From<crate::crypto::Error> for SwapError {
fn from(e: crate::crypto::Error) -> Self {
SwapError::Crypto { msg: e.to_string() }
}
}
impl From<crate::fake::FakeError> for SwapError {
fn from(e: crate::fake::FakeError) -> Self {
SwapError::Fake { msg: e.to_string() }
}
}
use crate::serde_helpers::base64_vec as base64_serde;