use crate::{error::AdesError, levels, signer::Signer, tsp::TspClient};
#[cfg(all(feature = "cades", feature = "tsp"))]
pub fn sign_t<S>(data: &[u8], signer: &S, tsa: &TspClient) -> Result<Vec<u8>, AdesError>
where
S: Signer,
S::Error: std::error::Error + Send + Sync + 'static,
{
let bb = crate::cades::sign(data, signer)?;
let sig_value = extract_signature_value(&bb)?;
let digest_algo = signer.digest_algorithm();
let hash = digest_algo.hash(&sig_value);
let tst = tsa.timestamp(&hash, digest_algo)?;
levels::add_signature_timestamp(&bb, &tst)
}
#[cfg(all(feature = "cades", feature = "tsp", feature = "ocsp"))]
pub fn sign_lt<S>(
data: &[u8],
signer: &S,
tsa: &TspClient,
ocsp: &crate::ocsp::OcspClient,
) -> Result<Vec<u8>, AdesError>
where
S: Signer,
S::Error: std::error::Error + Send + Sync + 'static,
{
let bt = sign_t(data, signer, tsa)?;
let cert = signer.certificate();
let ocsp_resp = match ocsp.raw_response(cert, cert) {
Ok(resp) => resp,
Err(AdesError::Ocsp(_)) => {
return Ok(bt);
}
Err(e) => return Err(e),
};
levels::add_revocation_values(&bt, &ocsp_resp)
}
fn extract_signature_value(cms_der: &[u8]) -> Result<Vec<u8>, AdesError> {
use cms::{content_info::ContentInfo, signed_data::SignedData};
use der::{Decode, Encode};
let ci = ContentInfo::from_der(cms_der)?;
let sd = SignedData::from_der(&ci.content.to_der()?)?;
let si = sd
.signer_infos
.0
.as_ref()
.first()
.ok_or(AdesError::NotImplemented("CMS has no signer infos"))?;
Ok(si.signature.as_bytes().to_vec())
}