use pyo3::exceptions::PyValueError;
use pyo3::prelude::*;
use pyo3::types::PyBytes;
use synta::traits::Decode;
use super::proof::PyHashAlgorithm;
#[pyfunction]
pub fn extract_leaf_index(serial: u64) -> u64 {
serial & 0xFFFF_FFFF_FFFF
}
#[pyfunction]
pub fn extract_log_number(serial: u64) -> u64 {
serial >> 48
}
#[pyfunction]
pub fn build_mtc_ca_extension<'py>(
py: Python<'py>,
hash_alg: &PyHashAlgorithm,
sig_alg_der: &[u8],
min_serial: u64,
) -> PyResult<(Bound<'py, PyBytes>, bool)> {
use synta_certificate::AlgorithmIdentifier;
let mut dec = synta::Decoder::new(sig_alg_der, synta::Encoding::Der);
let sig_alg = AlgorithmIdentifier::decode(&mut dec)
.map_err(|e| PyValueError::new_err(format!("invalid AlgorithmIdentifier DER: {e}")))?;
let der = synta_mtc::builder::ca_extension::build_mtc_ca_extension_from_hash(
hash_alg.inner,
&sig_alg,
min_serial,
u64::MAX, )
.map_err(|e| PyValueError::new_err(e.to_string()))?;
Ok((PyBytes::new(py, &der), true))
}
#[pyfunction]
#[allow(clippy::type_complexity)]
pub fn parse_mtc_ca_extension<'py>(
py: Python<'py>,
cert_der: &[u8],
) -> PyResult<Option<(Py<PyHashAlgorithm>, u64, u64)>> {
use synta_mtc::builder::ca_extension::parse_mtc_ca_extension as rust_parse;
let parsed = rust_parse(cert_der).map_err(|e| PyValueError::new_err(e.to_string()))?;
match parsed {
None => Ok(None),
Some(ext) => {
let py_hash_alg = Py::new(
py,
PyHashAlgorithm {
inner: ext.log_hash,
},
)?;
Ok(Some((py_hash_alg, ext.min_serial, ext.max_serial)))
}
}
}