coven_format/
sealed_single.rs1use crate::error::{bound, require, Error, Rule};
4use crate::sealed;
5use crate::wire::MAX_OBJECT;
6use coven_crypto::{Signature, SEALED_OBJECT_CHUNK_OVERHEAD};
7
8#[derive(Clone, Debug, PartialEq, Eq)]
10pub enum SingleChunkPrefix {
11 JoinRequest,
13}
14impl SingleChunkPrefix {
15 pub fn encode(&self) -> Result<Vec<u8>, Error> {
17 self.encode_in(crate::FormatVersion::CURRENT)
18 }
19 pub fn encode_in(&self, format: crate::FormatVersion) -> Result<Vec<u8>, Error> {
21 Ok(format.prefix(crate::kinds::JOIN_REQUEST).to_vec())
22 }
23 pub fn encode_chunk(&self, chunk: &[u8]) -> Result<Vec<u8>, Error> {
25 self.encode_chunk_in(crate::FormatVersion::CURRENT, chunk)
26 }
27 pub fn encode_chunk_in(
29 &self,
30 format: crate::FormatVersion,
31 chunk: &[u8],
32 ) -> Result<Vec<u8>, Error> {
33 check_frame_length(chunk)?;
34 let mut bytes = self.encode_in(format)?;
35 bytes.extend_from_slice(&sealed::encode_chunk(chunk)?);
36 Ok(bytes)
37 }
38}
39
40#[derive(Debug)]
42pub enum SingleChunkObject<'a> {
43 JoinRequest {
45 chunk: &'a [u8],
47 signature: Signature,
49 },
50}
51impl<'a> SingleChunkObject<'a> {
52 pub fn decode(bytes: &'a [u8]) -> Result<Self, Error> {
54 sealed::prefix(bytes, crate::kinds::JOIN_REQUEST)?;
55 let body = &bytes[3..];
56 let length = sealed::chunk_length(body, MAX_OBJECT)?;
57 let chunk = body.get(4..length).ok_or(Error::Truncated)?;
58 check_frame_length(chunk)?;
59 let signature = sealed::signature(body.get(length..).ok_or(Error::Truncated)?)?;
60 Ok(Self::JoinRequest { chunk, signature })
61 }
62 pub fn prefix(&self) -> SingleChunkPrefix {
64 SingleChunkPrefix::JoinRequest
65 }
66 pub fn chunk(&self) -> &'a [u8] {
68 let Self::JoinRequest { chunk, .. } = self;
69 chunk
70 }
71 pub fn signature(&self) -> &Signature {
73 let Self::JoinRequest { signature, .. } = self;
74 signature
75 }
76 pub fn encode(&self) -> Result<Vec<u8>, Error> {
78 let mut bytes = self.signed_bytes()?;
79 bytes.extend_from_slice(self.signature().as_bytes());
80 Ok(bytes)
81 }
82 pub fn signed_bytes(&self) -> Result<Vec<u8>, Error> {
84 self.prefix().encode_chunk(self.chunk())
85 }
86}
87
88fn check_frame_length(chunk: &[u8]) -> Result<(), Error> {
89 let length = chunk.len().checked_sub(SEALED_OBJECT_CHUNK_OVERHEAD).ok_or(Error::Truncated)?;
90 bound(length, MAX_OBJECT, "sealed frame")?;
91 require(length >= crate::FRAME_PREFIX_LEN, "sealed frame", Rule::Chunk)
92}
93
94#[cfg(test)]
95#[path = "sealed_single_tests.rs"]
96mod tests;