Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/security/manager/ssl/abridged_certs/src/   (Firefox Browser Version 153.0.1©)  Datei vom 27.6.2026 mit Größe 5 kB image not shown  

Quelle  lib.rs

  Sprache: Rust
 

/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */


mod builtins;
mod cert_storage;
mod tls;

use log;
use nserror::{nsresult, NS_ERROR_INVALID_ARG, NS_ERROR_UNEXPECTED, NS_OK};
use std::fmt::Display;
use std::io::Write;
use tls::{CertificateMessage, CompressedCertEntry, UncompressedCertEntry};

#[no_mangle]
pub extern "C" fn certs_are_available() -> bool {
    let Some(hashes) = builtins::get_needed_hashes() else {
        return false;
    };
    match cert_storage::has_all_certs_by_hash(hashes) {
        Ok(result) => {
            log::debug!("certs_are_available {}", result);
            return result;
        }
        Err(e) => {
            log::warn!("certs_are_available failed: {:?}", e);
            return false;
        }
    }
}

#[no_mangle]
pub unsafe extern "C" fn decompress(
    input: *const u8,
    input_len: usize,
    output: *mut u8,
    output_len: usize,
    used_len: *mut usize,
) -> nsresult {
    if input.is_null() || output.is_null() || used_len.is_null() {
        return NS_ERROR_INVALID_ARG;
    }
    let input_slice = unsafe { std::slice::from_raw_parts(input, input_len) };

    let mut output = unsafe {
        std::ptr::write_bytes(output, 0, output_len);
        std::slice::from_raw_parts_mut(output, output_len)
    };

    let size = match pass_1_decompression(input_slice, output_len, &mut output) {
        Ok(size) => size,
        Err(e) => {
            log::error!("Error during pass 1 decompression: {}", e);
            return NS_ERROR_UNEXPECTED;
        }
    };

    unsafe {
        *used_len = size;
    }

    log::debug!(
        "successfully decompressed {} input bytes to {} output_bytes ",
        input_len,
        size,
    );
    NS_OK
}

fn pass_1_mapping(mut entry: UncompressedCertEntry) -> Result<CompressedCertEntry, AbridgedError> {
    let id_or_cert = &entry.data;
    let Ok(id) = TryInto::<&[u8; 3]>::try_into(id_or_cert.as_slice()) else {
        // Avoid doing a lookup when we know its not an identifier.
        log::trace!("Passing through directly {:#02X?}", entry.data);
        return Ok(entry);
    };

    log::trace!("Abridged Certs Identifier: {:#02X?}", id);
    let Some(hash) = builtins::id_to_hash(id) else {
        return Err(AbridgedError::UnknownIdentifier(id_or_cert.to_vec()));
    };

    match cert_storage::get_cert_from_hash(&hash) {
        Ok(cert_bytes) => entry.data = cert_bytes.to_vec(),
        Err(err) => {
            return Err(AbridgedError::UnableToLoadCertByHash(hash.to_vec(), err));
        }
    };
    Ok(entry)
}
fn pass_1_decompression(
    input: &[u8],
    expected_len: usize,
    output: &mut impl Write,
) -> Result<usize, AbridgedError> {
    let (mut cert_msg, tail) = CertificateMessage::read_from_bytes(&input)?;

    if !tail.is_empty() {
        // Trailing data on a certificate message is forbidden by Abridged Certs spec
        return Err(AbridgedError::ParsingInvalidCertificateMessage);
    }

    let mut new_entries = Vec::with_capacity(cert_msg.certificate_entries.len());

    // We keep a running tally of the decompressed message's size.
    let mut current_size = cert_msg.get_size();

    for entry in cert_msg.certificate_entries {
        current_size -= entry.get_size();
        let mapping = pass_1_mapping(entry)?;
        current_size += mapping.get_size();
        new_entries.push(mapping);
        if current_size > expected_len {
            return Err(AbridgedError::LargerThanExpectedSize(expected_len));
        }
    }
    cert_msg.certificate_entries = new_entries;
    assert_eq!(current_size, cert_msg.get_size());
    cert_msg.write_to_bytes(output)?;
    Ok(cert_msg.get_size())
}

#[derive(Debug)]
pub enum AbridgedError {
    UnknownError,
    ParsingInvalidTLSVec,
    ParsingInvalidCertificateMessage,
    InvalidOperation,
    LargerThanExpectedSize(usize),
    ReadingError(std::io::Error),
    WritingError(std::io::Error),
    UnableToLoadCertByHash(Vec<u8>, nsresult),
    UnknownIdentifier(Vec<u8>),
}

impl Display for AbridgedError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            AbridgedError::UnknownError => write!(f, "Unknown Error"),
            AbridgedError::ParsingInvalidTLSVec => write!(f, "ParsingInvalidTLSVec"),
            AbridgedError::ParsingInvalidCertificateMessage => {
                write!(f, "ParsingInvalidCertificateMessage")
            }
            AbridgedError::InvalidOperation => write!(f, "InvalidOperation"),
            AbridgedError::LargerThanExpectedSize(size) => {
                write!(f, "Larger Than Expected Sizes {}", size)
            }
            AbridgedError::ReadingError(x) => write!(f, "Writing Error {}", x),
            AbridgedError::WritingError(x) => write!(f, "Writing Error {}", x),
            AbridgedError::UnableToLoadCertByHash(hash, error) => write!(
                f,
                "Unable to Load Cert for Hash {:#02X?}. Error: {}",
                hash, error
            ),
            AbridgedError::UnknownIdentifier(id) => {
                write!(f, "Unrecognized Identifier {:#02X?}", id)
            }
        }
    }
}

Messung V0.5 in Prozent
C=96 H=96 G=95

¤ Dauer der Verarbeitung: 0.15 Sekunden  (vorverarbeitet am  2026-08-25) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.