sare_core/format/
signature.rs

1use std::io::Cursor;
2
3use serde::{Deserialize, Serialize};
4
5use crate::format::EncodablePublic;
6use crate::format::error::{ErrSection, FormatError};
7use crate::hybrid_sign::{ECAlgorithm, PQAlgorithm};
8use byteorder::{LittleEndian, ReadBytesExt};
9
10pub const SIGNATURE_TAG: &str = "SARE MESSAGE";
11pub const SIGNATURE_MAGIC_BYTE: &[u8; 8] = b"SARESIGN";
12
13#[derive(Clone, Debug, Serialize, Deserialize)]
14pub struct SignatureMetadataFormat {
15    pub ec_algorithm: ECAlgorithm,
16    pub pq_algorithm: PQAlgorithm,
17}
18
19#[derive(Clone, Debug, Serialize, Deserialize)]
20pub struct SignatureFormat {
21    #[serde(skip_serializing_if = "Option::is_none", flatten)]
22    pub signature_metadata: Option<SignatureMetadataFormat>,
23    pub ec_public_key: Vec<u8>,
24    pub pq_public_key: Vec<u8>,
25    pub message: Option<Vec<u8>>, // Some(msg) would be attached & None would be detached signatures
26    pub ec_signature: Vec<u8>,
27    pub pq_signature: Vec<u8>,
28    pub fullchain_fingerprint: [u8; 32],
29}
30
31#[derive(Serialize, Deserialize, Clone)]
32pub struct SignatureHeaderFormat {
33    pub version: u32,
34    pub signature: SignatureFormat,
35}
36
37impl SignatureHeaderFormat {
38    fn verify_magic_bytes(header: &[u8], cursor: &mut usize) -> Result<bool, FormatError> {
39        let magic_bytes = &header[*cursor..*cursor + SIGNATURE_MAGIC_BYTE.len()];
40        *cursor += SIGNATURE_MAGIC_BYTE.len();
41        Ok(magic_bytes == SIGNATURE_MAGIC_BYTE)
42    }
43
44    fn read_u32(header: &[u8], cursor: &mut usize) -> Result<u32, FormatError> {
45        let mut rdr = Cursor::new(&header[*cursor..*cursor + 4]);
46        *cursor += 4;
47        rdr.read_u32::<LittleEndian>()
48            .map_err(|_| FormatError::FailedToDecode(ErrSection::HEADER))
49    }
50
51    pub fn encode_with_magic_byte(&self) -> Vec<u8> {
52        let mut header: Vec<u8> = Vec::new();
53        header.extend(SIGNATURE_MAGIC_BYTE);
54        header.extend(self.version.to_le_bytes());
55        header.extend_from_slice(&self.signature.encode_bson());
56
57        header
58    }
59
60    pub fn decode_with_magic_byte(signature_header: &[u8]) -> Result<Self, FormatError> {
61        let mut cursor = 0;
62
63        if !Self::verify_magic_bytes(signature_header, &mut cursor)? {
64            return Err(FormatError::FailedToDecode(ErrSection::HEADER));
65        }
66
67        let version = Self::read_u32(signature_header, &mut cursor)?;
68
69        let bson_data = &signature_header[cursor..];
70        let signature = SignatureFormat::decode_bson(bson_data)?;
71
72        Ok(SignatureHeaderFormat { version, signature })
73    }
74}
75
76impl EncodablePublic for SignatureFormat {
77    fn encode_bson(&self) -> Vec<u8> {
78        bson::to_vec(&self).unwrap()
79    }
80
81    fn decode_bson(data: &[u8]) -> Result<Self, FormatError> {
82        let metadata = bson::from_slice::<SignatureFormat>(data);
83
84        Ok(metadata?)
85    }
86
87    fn encode_pem(&self) -> String {
88        let pem = pem::Pem::new(SIGNATURE_TAG, self.encode_bson());
89        pem::encode(&pem)
90    }
91
92    fn decode_pem(pem_data: &str) -> Result<Self, FormatError> {
93        let pem = pem::parse(pem_data)?;
94
95        let bson_data = pem.contents();
96        Self::decode_bson(bson_data)
97    }
98}