use std::mem;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
use crate::MyReader;
use crate::add_space;
use crate::common::AdditionalAttributes;
use crate::common::Certificates;
use crate::common::Digests;
use crate::common::PubKey;
use crate::common::Signatures;
use crate::utils::print_string;
pub const SIGNATURE_SCHEME_V2_BLOCK_ID: u32 = 0x7109871a;
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct SignatureSchemeV2 {
pub size: usize,
pub id: u32,
pub signers: Signers,
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Signers {
pub size: usize,
pub signers_data: Vec<Signer>,
}
impl Signers {
pub fn new(signers_data: Vec<Signer>) -> Self {
let size = signers_data
.iter()
.fold(0, |acc, s| acc + s.size + mem::size_of::<u32>());
Self { size, signers_data }
}
pub fn parse(data: &mut MyReader) -> Result<Self, String> {
let size_signers = data.read_size()?;
let mut signers = Self {
size: size_signers,
signers_data: Vec::new(),
};
add_space!(4);
print_string!("size_signers: {}", size_signers);
let data = &mut data.as_slice(size_signers)?;
while data.get_pos() < data.len() {
let signer = Signer::parse(data)?;
signers.signers_data.push(signer);
}
Ok(signers)
}
pub fn to_u8(&self) -> Vec<u8> {
let content = self
.signers_data
.iter()
.flat_map(|s| s.to_u8())
.collect::<Vec<u8>>();
let padding = self
.size
.checked_sub(content.len())
.map_or_else(std::vec::Vec::new, |calculated_size| {
vec![0; calculated_size]
});
[(self.size as u32).to_le_bytes().to_vec(), content, padding].concat()
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct Signer {
pub size: usize,
pub signed_data: SignedData,
pub signatures: Signatures,
pub pub_key: PubKey,
}
impl Signer {
pub const fn new(signed_data: SignedData, signatures: Signatures, pub_key: PubKey) -> Self {
let size = mem::size_of::<u32>()
+ signed_data.size
+ mem::size_of::<u32>()
+ signatures.size
+ mem::size_of::<u32>()
+ pub_key.size;
Self {
size,
signed_data,
signatures,
pub_key,
}
}
pub fn parse(data: &mut MyReader) -> Result<Self, String> {
let size_one_signer = data.read_size()?;
add_space!(8);
print_string!("size_one_signer: {}", size_one_signer);
let signed_data = SignedData::parse(data)?;
let signatures = Signatures::parse(data)?;
let pub_key = PubKey::parse(data)?;
Ok(Self {
size: size_one_signer,
signed_data,
signatures,
pub_key,
})
}
pub fn to_u8(&self) -> Vec<u8> {
let content = [
self.signed_data.to_u8(),
self.signatures.to_u8(),
self.pub_key.to_u8(),
]
.concat();
let padding = self
.size
.checked_sub(content.len())
.map_or_else(std::vec::Vec::new, |calculated_size| {
vec![0; calculated_size]
});
[(self.size as u32).to_le_bytes().to_vec(), content, padding].concat()
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct SignedData {
pub size: usize,
pub digests: Digests,
pub certificates: Certificates,
pub additional_attributes: AdditionalAttributes,
pub _private_auto_padding_fix: bool,
}
impl SignedData {
pub const fn new(
digests: Digests,
certificates: Certificates,
additional_attributes: AdditionalAttributes,
) -> Self {
let auto_padding_fix = true;
let size = mem::size_of::<u32>()
+ digests.size
+ mem::size_of::<u32>()
+ certificates.size
+ mem::size_of::<u32>()
+ additional_attributes.size;
let size = if auto_padding_fix { size + 4 } else { size };
Self {
size,
digests,
certificates,
additional_attributes,
_private_auto_padding_fix: auto_padding_fix,
}
}
pub fn parse(data: &mut MyReader) -> Result<Self, String> {
let size_signed_data = data.read_size()?;
add_space!(8);
print_string!("size_signed_data: {}", size_signed_data);
let data = &mut data.as_slice(size_signed_data)?;
let digests = Digests::parse(data)?;
let certificates = Certificates::parse(data)?;
let additional_attributes = AdditionalAttributes::parse(data)?;
Ok(Self {
size: size_signed_data,
digests,
certificates,
additional_attributes,
_private_auto_padding_fix: true,
})
}
pub fn to_u8(&self) -> Vec<u8> {
let content = [
self.digests.to_u8(),
self.certificates.to_u8(),
self.additional_attributes.to_u8(),
]
.concat();
let padding = self
.size
.checked_sub(content.len())
.map_or_else(std::vec::Vec::new, |calculated_size| {
vec![0; calculated_size]
});
[(self.size as u32).to_le_bytes().to_vec(), content, padding].concat()
}
}
impl SignatureSchemeV2 {
pub const fn new(signers: Signers) -> Self {
let size = mem::size_of::<u32>() + mem::size_of::<u32>() + signers.size;
Self {
size,
id: SIGNATURE_SCHEME_V2_BLOCK_ID,
signers,
}
}
pub fn parse(size: usize, id: u32, data: &mut MyReader) -> Result<Self, String> {
Ok(Self {
size,
id,
signers: Signers::parse(data)?,
})
}
pub fn to_u8(&self) -> Vec<u8> {
let content = [self.id.to_le_bytes().to_vec(), self.signers.to_u8()].concat();
let padding = self
.size
.checked_sub(content.len())
.map_or_else(std::vec::Vec::new, |calculated_size| {
vec![0; calculated_size]
});
[(self.size as u64).to_le_bytes().to_vec(), content, padding].concat()
}
}