use crate::timestamp::{self, TimestampInfo};
use authenticode::AuthenticodeSignature;
use cms::signed_data::SignerIdentifier;
use x509_cert::Certificate;
#[derive(Debug, Clone)]
pub struct SignatureInfo {
pub digest_algo_oid: String,
pub has_timestamp: bool,
pub timestamp: Option<TimestampInfo>,
pub leaf_cert: Option<Certificate>,
}
const OID_MS_TIMESTAMP: &str = "1.3.6.1.4.1.311.3.3.1"; const OID_COUNTERSIGNATURE: &str = "1.2.840.113549.1.9.6";
pub fn from_authenticode(sig: &AuthenticodeSignature) -> SignatureInfo {
let si = sig.signer_info();
let digest_algo_oid = si.digest_alg.oid.to_string();
let has_timestamp = si.unsigned_attrs.as_ref().is_some_and(|attrs| {
attrs.iter().any(|a| {
let oid = a.oid.to_string();
oid == OID_MS_TIMESTAMP || oid == OID_COUNTERSIGNATURE
})
});
let leaf_cert = match &si.sid {
SignerIdentifier::IssuerAndSerialNumber(isn) => sig
.certificates()
.find(|c| {
c.tbs_certificate.issuer == isn.issuer
&& c.tbs_certificate.serial_number == isn.serial_number
})
.cloned(),
SignerIdentifier::SubjectKeyIdentifier(_) => None,
};
SignatureInfo {
digest_algo_oid,
has_timestamp,
timestamp: timestamp::from_unsigned_attrs(si.unsigned_attrs.as_ref()),
leaf_cert,
}
}