tasign 0.1.2

TA ELF signing utilities with CMS/PKCS#7 support
Documentation
//! 验签路径上的资源上限(缓解对不可信 ELF/CMS 输入的内存型 DoS)。

use core::fmt;

/// 超过 [`VerifyLimits`] 时返回;由 [`crate::plain::PlainError::ResourceLimit`] 或 [`crate::error::Error::ResourceLimit`] 承载。
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct LimitsError {
    pub context: &'static str,
    pub max: usize,
    pub got: usize,
}

impl fmt::Display for LimitsError {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(
            f,
            "超过资源上限 ({}): 允许至多 {}, 实际 {}",
            self.context, self.max, self.got
        )
    }
}

impl core::error::Error for LimitsError {}

/// 内核/用户态验签共用的一组保守默认阈值;可通过 [`VerifyLimits::recommended`] 或自定义结构体调整策略。
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct VerifyLimits {
    /// 整颗 ELF 文件最大字节数(`build_plain_bin` / `plain_bytes_from_signed_elf` / `ta_signature_section_bytes` 入口)。
    pub max_elf_bytes: usize,
    /// `.ta_signature` 节载荷(PKCS#7 DER)最大长度。
    pub max_ta_signature_section_bytes: usize,
    /// `plain` 拼接结果最大长度。
    pub max_plain_output_bytes: usize,
    /// 独立传入的 CMS/PKCS#7 DER 最大长度(`verify_cms_signature_with_ca_opt` 等)。
    pub max_cms_der_bytes: usize,
    /// `SignedData.certificates` 中证书项最大个数(仅 `Certificate` 选择)。
    pub max_embedded_certificates: usize,
    /// 单张嵌入证书 DER 最大字节数。
    pub max_certificate_der_bytes: usize,
    /// 所有嵌入证书 DER 长度之和上限。
    pub max_total_embedded_cert_der_bytes: usize,
    /// ELF section header 表项数上限(解析后)。
    pub max_section_headers: usize,
    /// ELF program header 表项数上限(解析后)。
    pub max_program_headers: usize,
}

impl Default for VerifyLimits {
    fn default() -> Self {
        Self::recommended()
    }
}

impl VerifyLimits {
    /// 面向不可信输入的保守默认值(可在集成时整体替换为更严或更松的策略)。
    pub const fn recommended() -> Self {
        Self {
            max_elf_bytes: 64 * 1024 * 1024,
            max_ta_signature_section_bytes: 4 * 1024 * 1024,
            max_plain_output_bytes: 96 * 1024 * 1024,
            max_cms_der_bytes: 8 * 1024 * 1024,
            max_embedded_certificates: 32,
            max_certificate_der_bytes: 256 * 1024,
            max_total_embedded_cert_der_bytes: 512 * 1024,
            max_section_headers: 65536,
            max_program_headers: 4096,
        }
    }

    pub fn check_elf_input_len(&self, got: usize) -> Result<(), LimitsError> {
        if got > self.max_elf_bytes {
            Err(LimitsError {
                context: "ELF 输入长度",
                max: self.max_elf_bytes,
                got,
            })
        } else {
            Ok(())
        }
    }

    pub fn check_ta_signature_payload_len(&self, got: usize) -> Result<(), LimitsError> {
        if got > self.max_ta_signature_section_bytes {
            Err(LimitsError {
                context: ".ta_signature 节长度",
                max: self.max_ta_signature_section_bytes,
                got,
            })
        } else {
            Ok(())
        }
    }

    pub fn check_plain_buffer_len(&self, got: usize) -> Result<(), LimitsError> {
        if got > self.max_plain_output_bytes {
            Err(LimitsError {
                context: "plain 缓冲区长度",
                max: self.max_plain_output_bytes,
                got,
            })
        } else {
            Ok(())
        }
    }

    pub fn check_cms_der_len(&self, got: usize) -> Result<(), LimitsError> {
        if got > self.max_cms_der_bytes {
            Err(LimitsError {
                context: "CMS/PKCS#7 DER 长度",
                max: self.max_cms_der_bytes,
                got,
            })
        } else {
            Ok(())
        }
    }

    pub fn check_section_header_count(&self, got: usize) -> Result<(), LimitsError> {
        if got > self.max_section_headers {
            Err(LimitsError {
                context: "ELF 节头数量",
                max: self.max_section_headers,
                got,
            })
        } else {
            Ok(())
        }
    }

    pub fn check_program_header_count(&self, got: usize) -> Result<(), LimitsError> {
        if got > self.max_program_headers {
            Err(LimitsError {
                context: "ELF 程序头数量",
                max: self.max_program_headers,
                got,
            })
        } else {
            Ok(())
        }
    }
}