LCOV - code coverage report
Current view: top level - src/pe/signature - attributes.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 91.3 % 300 274
Test Date: 2026-04-12:00:00:00 Functions: 83.0 % 47 39

            Line data    Source code
       1              : use std::marker::PhantomData;
       2              : 
       3              : use lief_ffi as ffi;
       4              : 
       5              : use crate::common::FromFFI;
       6              : use crate::declare_iterator;
       7              : use crate::pe::signature::ContentInfo;
       8              : use crate::pe::signature::X509;
       9              : use crate::pe::Algorithms;
      10              : use crate::to_slice;
      11              : 
      12              : use super::{Signature, SignerInfo};
      13              : 
      14            0 : #[derive(Debug)]
      15              : /// This enum exposes the different attributes that can be wrapped in
      16              : /// a [`crate::pe::signature::SignerInfo`]
      17              : pub enum Attribute<'a> {
      18              :     /// Attribute for the OID: `1.2.840.113549.1.9.3`
      19              :     ContentType(ContentType<'a>),
      20              :     /// Attribute for the OID: `1.3.6.1.4.1.311.2.4.1`
      21              :     MsSpcNestedSignature(MsSpcNestedSignature<'a>),
      22              :     /// Attribute for the OID: `1.3.6.1.4.1.311.2.1.11`
      23              :     MsSpcStatementType(MsSpcStatementType<'a>),
      24              :     /// Attribute for the OID: `1.2.840.113549.1.9.25.4`
      25              :     PKCS9AtSequenceNumber(PKCS9AtSequenceNumber<'a>),
      26              :     /// Attribute for the OID: `1.2.840.113549.1.9.6`
      27              :     PKCS9CounterSignature(PKCS9CounterSignature<'a>),
      28              :     /// Attribute for the OID: `1.2.840.113549.1.9.4`
      29              :     PKCS9MessageDigest(PKCS9MessageDigest<'a>),
      30              :     /// Attribute for the OID: `1.2.840.113549.1.9.5`
      31              :     PKCS9SigningTime(PKCS9SigningTime<'a>),
      32              :     /// Attribute for the OID: `1.3.6.1.4.1.311.2.1.12`
      33              :     SpcSpOpusInfo(SpcSpOpusInfo<'a>),
      34              :     /// Attribute for the OID: `1.3.6.1.4.1.311.10.3.28`
      35              :     MsManifestBinaryID(MsManifestBinaryID<'a>),
      36              :     /// Attribute for the OID: `1.3.6.1.4.1.311.3.3.1`
      37              :     MsCounterSign(MsCounterSign<'a>),
      38              :     /// Attribute for the OID: `1.2.840.113549.1.9.16.2.47`
      39              :     SigningCertificateV2(SigningCertificateV2<'a>),
      40              :     /// Attribute for the OID: `1.3.6.1.4.1.311.2.6.1`
      41              :     SpcRelaxedPeMarkerCheck(SpcRelaxedPeMarkerCheck<'a>),
      42              :     /// Attribute for an OID not supported by LIEF
      43              :     GenericType(GenericType<'a>),
      44              : }
      45              : 
      46              : impl<'a> FromFFI<ffi::PE_Attribute> for Attribute<'a> {
      47         1664 :     fn from_ffi(ffi_entry: cxx::UniquePtr<ffi::PE_Attribute>) -> Self {
      48         1664 :         unsafe {
      49         1664 :             let cmd_ref = ffi_entry.as_ref().unwrap();
      50         1664 : 
      51         1664 :             if ffi::PE_ContentType::classof(cmd_ref) {
      52          390 :                 let raw = {
      53          390 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
      54          390 :                     type To = cxx::UniquePtr<ffi::PE_ContentType>;
      55          390 :                     std::mem::transmute::<From, To>(ffi_entry)
      56          390 :                 };
      57          390 :                 Attribute::ContentType(ContentType::from_ffi(raw))
      58         1274 :             } else if ffi::PE_MsSpcNestedSignature::classof(cmd_ref) {
      59           39 :                 let raw = {
      60           39 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
      61           39 :                     type To = cxx::UniquePtr<ffi::PE_MsSpcNestedSignature>;
      62           39 :                     std::mem::transmute::<From, To>(ffi_entry)
      63           39 :                 };
      64           39 :                 Attribute::MsSpcNestedSignature(MsSpcNestedSignature::from_ffi(raw))
      65         1235 :             } else if ffi::PE_MsSpcStatementType::classof(cmd_ref) {
      66          182 :                 let raw = {
      67          182 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
      68          182 :                     type To = cxx::UniquePtr<ffi::PE_MsSpcStatementType>;
      69          182 :                     std::mem::transmute::<From, To>(ffi_entry)
      70          182 :                 };
      71          182 :                 Attribute::MsSpcStatementType(MsSpcStatementType::from_ffi(raw))
      72         1053 :             } else if ffi::PE_PKCS9AtSequenceNumber::classof(cmd_ref) {
      73           26 :                 let raw = {
      74           26 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
      75           26 :                     type To = cxx::UniquePtr<ffi::PE_PKCS9AtSequenceNumber>;
      76           26 :                     std::mem::transmute::<From, To>(ffi_entry)
      77           26 :                 };
      78           26 :                 Attribute::PKCS9AtSequenceNumber(PKCS9AtSequenceNumber::from_ffi(raw))
      79         1027 :             } else if ffi::PE_PKCS9CounterSignature::classof(cmd_ref) {
      80           65 :                 let raw = {
      81           65 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
      82           65 :                     type To = cxx::UniquePtr<ffi::PE_PKCS9CounterSignature>;
      83           65 :                     std::mem::transmute::<From, To>(ffi_entry)
      84           65 :                 };
      85           65 :                 Attribute::PKCS9CounterSignature(PKCS9CounterSignature::from_ffi(raw))
      86          962 :             } else if ffi::PE_PKCS9MessageDigest::classof(cmd_ref) {
      87          390 :                 let raw = {
      88          390 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
      89          390 :                     type To = cxx::UniquePtr<ffi::PE_PKCS9MessageDigest>;
      90          390 :                     std::mem::transmute::<From, To>(ffi_entry)
      91          390 :                 };
      92          390 :                 Attribute::PKCS9MessageDigest(PKCS9MessageDigest::from_ffi(raw))
      93          572 :             } else if ffi::PE_PKCS9SigningTime::classof(cmd_ref) {
      94          143 :                 let raw = {
      95          143 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
      96          143 :                     type To = cxx::UniquePtr<ffi::PE_PKCS9SigningTime>;
      97          143 :                     std::mem::transmute::<From, To>(ffi_entry)
      98          143 :                 };
      99          143 :                 Attribute::PKCS9SigningTime(PKCS9SigningTime::from_ffi(raw))
     100          429 :             } else if ffi::PE_SpcSpOpusInfo::classof(cmd_ref) {
     101          156 :                 let raw = {
     102          156 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
     103          156 :                     type To = cxx::UniquePtr<ffi::PE_SpcSpOpusInfo>;
     104          156 :                     std::mem::transmute::<From, To>(ffi_entry)
     105          156 :                 };
     106          156 :                 Attribute::SpcSpOpusInfo(SpcSpOpusInfo::from_ffi(raw))
     107          273 :             } else if ffi::PE_MsManifestBinaryID::classof(cmd_ref) {
     108           13 :                 let raw = {
     109           13 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
     110           13 :                     type To = cxx::UniquePtr<ffi::PE_MsManifestBinaryID>;
     111           13 :                     std::mem::transmute::<From, To>(ffi_entry)
     112           13 :                 };
     113           13 :                 Attribute::MsManifestBinaryID(MsManifestBinaryID::from_ffi(raw))
     114          260 :             } else if ffi::PE_MsCounterSign::classof(cmd_ref) {
     115          117 :                 let raw = {
     116          117 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
     117          117 :                     type To = cxx::UniquePtr<ffi::PE_MsCounterSign>;
     118          117 :                     std::mem::transmute::<From, To>(ffi_entry)
     119          117 :                 };
     120          117 :                 Attribute::MsCounterSign(MsCounterSign::from_ffi(raw))
     121          143 :             } else if ffi::PE_SpcRelaxedPeMarkerCheck::classof(cmd_ref) {
     122           26 :                 let raw = {
     123           26 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
     124           26 :                     type To = cxx::UniquePtr<ffi::PE_SpcRelaxedPeMarkerCheck>;
     125           26 :                     std::mem::transmute::<From, To>(ffi_entry)
     126           26 :                 };
     127           26 :                 Attribute::SpcRelaxedPeMarkerCheck(SpcRelaxedPeMarkerCheck::from_ffi(raw))
     128          117 :             } else if ffi::PE_SigningCertificateV2::classof(cmd_ref) {
     129           78 :                 let raw = {
     130           78 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
     131           78 :                     type To = cxx::UniquePtr<ffi::PE_SigningCertificateV2>;
     132           78 :                     std::mem::transmute::<From, To>(ffi_entry)
     133           78 :                 };
     134           78 :                 Attribute::SigningCertificateV2(SigningCertificateV2::from_ffi(raw))
     135              :             } else {
     136           39 :                 assert!(
     137           39 :                     ffi::PE_GenericType::classof(cmd_ref),
     138            0 :                     "Must be a GenericType node"
     139              :                 );
     140           39 :                 let raw = {
     141           39 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
     142           39 :                     type To = cxx::UniquePtr<ffi::PE_GenericType>;
     143           39 :                     std::mem::transmute::<From, To>(ffi_entry)
     144           39 :                 };
     145           39 :                 Attribute::GenericType(GenericType::from_ffi(raw))
     146              :             }
     147              :         }
     148         1664 :     }
     149              : }
     150              : /// Interface over the structure described by the OID ``1.2.840.113549.1.9.3`` (PKCS #9)
     151              : ///
     152              : /// The internal structure is described in the RFC #2985
     153              : ///
     154              : /// ```text
     155              : /// ContentType ::= OBJECT IDENTIFIER
     156              : /// ```
     157              : pub struct ContentType<'a> {
     158              :     ptr: cxx::UniquePtr<ffi::PE_ContentType>,
     159              :     _owner: PhantomData<&'a ffi::PE_SignerInfo>,
     160              : }
     161              : 
     162              : impl std::fmt::Debug for ContentType<'_> {
     163          390 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     164          390 :         f.debug_struct("ContentType")
     165          390 :             .field("oid", &self.oid())
     166          390 :             .finish()
     167          390 :     }
     168              : }
     169              : 
     170              : impl<'a> FromFFI<ffi::PE_ContentType> for ContentType<'a> {
     171          390 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_ContentType>) -> Self {
     172          390 :         Self {
     173          390 :             ptr,
     174          390 :             _owner: PhantomData,
     175          390 :         }
     176          390 :     }
     177              : }
     178              : 
     179              : impl ContentType<'_> {
     180              :     /// OID as described in RFC #2985
     181          390 :     pub fn oid(&self) -> String {
     182          390 :         self.ptr.oid().to_string()
     183          390 :     }
     184              : }
     185              : 
     186              : /// Interface over an attribute for which the internal structure is not supported by LIEF
     187              : pub struct GenericType<'a> {
     188              :     ptr: cxx::UniquePtr<ffi::PE_GenericType>,
     189              :     _owner: PhantomData<&'a ffi::PE_SignerInfo>,
     190              : }
     191              : 
     192              : impl std::fmt::Debug for GenericType<'_> {
     193           39 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     194           39 :         f.debug_struct("GenericType")
     195           39 :             .field("oid", &self.oid())
     196           39 :             .finish()
     197           39 :     }
     198              : }
     199              : 
     200              : impl<'a> FromFFI<ffi::PE_GenericType> for GenericType<'a> {
     201           39 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_GenericType>) -> Self {
     202           39 :         Self {
     203           39 :             ptr,
     204           39 :             _owner: PhantomData,
     205           39 :         }
     206           39 :     }
     207              : }
     208              : 
     209              : impl GenericType<'_> {
     210              :     /// OID of the original attribute
     211           39 :     pub fn oid(&self) -> String {
     212           39 :         self.ptr.oid().to_string()
     213           39 :     }
     214              : 
     215              :     /// Original DER blob of the attribute
     216            0 :     pub fn raw_content(&self) -> &[u8] {
     217            0 :         to_slice!(self.ptr.raw_content());
     218            0 :     }
     219              : }
     220              : 
     221              : /// Interface over the structure described by the OID `1.3.6.1.4.1.311.2.4.1`
     222              : ///
     223              : /// The internal structure is not documented but we can infer the following structure:
     224              : ///
     225              : /// ```text
     226              : /// MsSpcNestedSignature ::= SET OF SignedData
     227              : /// ```
     228              : ///
     229              : /// `SignedData` is the structure described in PKCS #7 RFC
     230              : pub struct MsSpcNestedSignature<'a> {
     231              :     ptr: cxx::UniquePtr<ffi::PE_MsSpcNestedSignature>,
     232              :     _owner: PhantomData<&'a ffi::PE_SignerInfo>,
     233              : }
     234              : 
     235              : impl std::fmt::Debug for MsSpcNestedSignature<'_> {
     236           39 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     237           39 :         f.debug_struct("MsSpcNestedSignature").finish()
     238           39 :     }
     239              : }
     240              : 
     241              : impl<'a> FromFFI<ffi::PE_MsSpcNestedSignature> for MsSpcNestedSignature<'a> {
     242           39 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_MsSpcNestedSignature>) -> Self {
     243           39 :         Self {
     244           39 :             ptr,
     245           39 :             _owner: PhantomData,
     246           39 :         }
     247           39 :     }
     248              : }
     249              : 
     250              : impl MsSpcNestedSignature<'_> {
     251              :     /// Underlying Signature object
     252           39 :     pub fn signature(&self) -> Signature<'_> {
     253           39 :         Signature::from_ffi(self.ptr.sig())
     254           39 :     }
     255              : }
     256              : 
     257              : /// Interface over the structure described by the OID `1.3.6.1.4.1.311.2.1.11`
     258              : ///
     259              : /// The internal structure is described in the official document:
     260              : /// *Windows Authenticode Portable Executable Signature Format*
     261              : ///
     262              : /// ```text
     263              : /// SpcStatementType ::= SEQUENCE of OBJECT IDENTIFIER
     264              : /// ```
     265              : pub struct MsSpcStatementType<'a> {
     266              :     ptr: cxx::UniquePtr<ffi::PE_MsSpcStatementType>,
     267              :     _owner: PhantomData<&'a ffi::PE_SignerInfo>,
     268              : }
     269              : 
     270              : impl std::fmt::Debug for MsSpcStatementType<'_> {
     271          182 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     272          182 :         f.debug_struct("MsSpcStatementType")
     273          182 :             .field("oid", &self.oid())
     274          182 :             .finish()
     275          182 :     }
     276              : }
     277              : 
     278              : impl<'a> FromFFI<ffi::PE_MsSpcStatementType> for MsSpcStatementType<'a> {
     279          182 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_MsSpcStatementType>) -> Self {
     280          182 :         Self {
     281          182 :             ptr,
     282          182 :             _owner: PhantomData,
     283          182 :         }
     284          182 :     }
     285              : }
     286              : 
     287              : impl MsSpcStatementType<'_> {
     288              :     /// According to the documentation:
     289              :     /// > The SpcStatementType MUST contain one Object Identifier with either
     290              :     /// > the value `1.3.6.1.4.1.311.2.1.21 (SPC_INDIVIDUAL_SP_KEY_PURPOSE_OBJID)` or
     291              :     /// > `1.3.6.1.4.1.311.2.1.22 (SPC_COMMERCIAL_SP_KEY_PURPOSE_OBJID)`.
     292          182 :     pub fn oid(&self) -> String {
     293          182 :         self.ptr.oid().to_string()
     294          182 :     }
     295              : }
     296              : 
     297              : /// Interface over the structure described by the OID `1.2.840.113549.1.9.25.4` (PKCS #9)
     298              : ///
     299              : /// The internal structure is described in the
     300              : /// RFC #2985: PKCS #9 - Selected Object Classes and Attribute Types Version 2.0
     301              : ///
     302              : /// ```text
     303              : /// sequenceNumber ATTRIBUTE ::= {
     304              : ///   WITH SYNTAX SequenceNumber
     305              : ///   EQUALITY MATCHING RULE integerMatch
     306              : ///   SINGLE VALUE TRUE
     307              : ///   ID pkcs-9-at-sequenceNumber
     308              : /// }
     309              : ///
     310              : /// SequenceNumber ::= INTEGER (1..MAX)
     311              : /// ```
     312              : pub struct PKCS9AtSequenceNumber<'a> {
     313              :     ptr: cxx::UniquePtr<ffi::PE_PKCS9AtSequenceNumber>,
     314              :     _owner: PhantomData<&'a ffi::PE_SignerInfo>,
     315              : }
     316              : 
     317              : impl std::fmt::Debug for PKCS9AtSequenceNumber<'_> {
     318           26 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     319           26 :         f.debug_struct("PKCS9AtSequenceNumber")
     320           26 :             .field("number", &self.number())
     321           26 :             .finish()
     322           26 :     }
     323              : }
     324              : 
     325              : impl PKCS9AtSequenceNumber<'_> {
     326              :     //! Number as described in the RFC
     327           26 :     pub fn number(&self) -> u32 {
     328           26 :         self.ptr.number()
     329           26 :     }
     330              : }
     331              : 
     332              : impl<'a> FromFFI<ffi::PE_PKCS9AtSequenceNumber> for PKCS9AtSequenceNumber<'a> {
     333           26 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_PKCS9AtSequenceNumber>) -> Self {
     334           26 :         Self {
     335           26 :             ptr,
     336           26 :             _owner: PhantomData,
     337           26 :         }
     338           26 :     }
     339              : }
     340              : 
     341              : /// Interface over the structure described by the OID `1.2.840.113549.1.9.6` (PKCS #9)
     342              : ///
     343              : /// The internal structure is described in the
     344              : /// RFC #2985: PKCS #9 - Selected Object Classes and Attribute Types Version 2.0
     345              : ///
     346              : /// ```text
     347              : /// counterSignature ATTRIBUTE ::= {
     348              : ///   WITH SYNTAX SignerInfo
     349              : ///   ID pkcs-9-at-counterSignature
     350              : /// }
     351              : /// ```
     352              : pub struct PKCS9CounterSignature<'a> {
     353              :     ptr: cxx::UniquePtr<ffi::PE_PKCS9CounterSignature>,
     354              :     _owner: PhantomData<&'a ffi::PE_SignerInfo>,
     355              : }
     356              : 
     357              : impl std::fmt::Debug for PKCS9CounterSignature<'_> {
     358           65 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     359           65 :         f.debug_struct("PKCS9CounterSignature").finish()
     360           65 :     }
     361              : }
     362              : 
     363              : impl<'a> FromFFI<ffi::PE_PKCS9CounterSignature> for PKCS9CounterSignature<'a> {
     364           65 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_PKCS9CounterSignature>) -> Self {
     365           65 :         Self {
     366           65 :             ptr,
     367           65 :             _owner: PhantomData,
     368           65 :         }
     369           65 :     }
     370              : }
     371              : 
     372              : impl PKCS9CounterSignature<'_> {
     373              :     /// SignerInfo as described in the RFC #2985
     374           65 :     pub fn signer(&self) -> SignerInfo<'_> {
     375           65 :         SignerInfo::from_ffi(self.ptr.signer())
     376           65 :     }
     377              : }
     378              : 
     379              : /// Interface over the structure described by the OID `1.2.840.113549.1.9.4` (PKCS #9)
     380              : ///
     381              : /// The internal structure is described in the
     382              : /// RFC #2985: PKCS #9 - Selected Object Classes and Attribute Types Version 2.0
     383              : ///
     384              : /// ```text
     385              : /// messageDigest ATTRIBUTE ::= {
     386              : ///   WITH SYNTAX MessageDigest
     387              : ///   EQUALITY MATCHING RULE octetStringMatch
     388              : ///   SINGLE VALUE TRUE
     389              : ///   ID pkcs-9-at-messageDigest
     390              : /// }
     391              : ///
     392              : /// MessageDigest ::= OCTET STRING
     393              : /// ```
     394              : pub struct PKCS9MessageDigest<'a> {
     395              :     ptr: cxx::UniquePtr<ffi::PE_PKCS9MessageDigest>,
     396              :     _owner: PhantomData<&'a ffi::PE_SignerInfo>,
     397              : }
     398              : 
     399              : impl std::fmt::Debug for PKCS9MessageDigest<'_> {
     400          390 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     401          390 :         f.debug_struct("PKCS9MessageDigest").finish()
     402          390 :     }
     403              : }
     404              : 
     405              : impl PKCS9MessageDigest<'_> {
     406              :     /// Message digeset as a blob of bytes as described in the RFC
     407          390 :     pub fn digest(&self) -> &[u8] {
     408          390 :         to_slice!(self.ptr.digest());
     409          390 :     }
     410              : }
     411              : 
     412              : impl<'a> FromFFI<ffi::PE_PKCS9MessageDigest> for PKCS9MessageDigest<'a> {
     413          390 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_PKCS9MessageDigest>) -> Self {
     414          390 :         Self {
     415          390 :             ptr,
     416          390 :             _owner: PhantomData,
     417          390 :         }
     418          390 :     }
     419              : }
     420              : 
     421              : /// Interface over the structure described by the OID `1.2.840.113549.1.9.5` (PKCS #9)
     422              : ///
     423              : /// The internal structure is described in the
     424              : /// RFC #2985: PKCS #9 - Selected Object Classes and Attribute Types Version 2.0
     425              : ///
     426              : /// ```text
     427              : /// signingTime ATTRIBUTE ::= {
     428              : ///         WITH SYNTAX SigningTime
     429              : ///         EQUALITY MATCHING RULE signingTimeMatch
     430              : ///         SINGLE VALUE TRUE
     431              : ///         ID pkcs-9-at-signingTime
     432              : /// }
     433              : ///
     434              : /// SigningTime ::= Time -- imported from ISO/IEC 9594-8
     435              : /// ```
     436              : pub struct PKCS9SigningTime<'a> {
     437              :     ptr: cxx::UniquePtr<ffi::PE_PKCS9SigningTime>,
     438              :     _owner: PhantomData<&'a ffi::PE_SignerInfo>,
     439              : }
     440              : 
     441              : impl std::fmt::Debug for PKCS9SigningTime<'_> {
     442          143 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     443          143 :         f.debug_struct("PKCS9SigningTime")
     444          143 :             .field("time", &self.time())
     445          143 :             .finish()
     446          143 :     }
     447              : }
     448              : 
     449              : impl<'a> FromFFI<ffi::PE_PKCS9SigningTime> for PKCS9SigningTime<'a> {
     450          143 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_PKCS9SigningTime>) -> Self {
     451          143 :         Self {
     452          143 :             ptr,
     453          143 :             _owner: PhantomData,
     454          143 :         }
     455          143 :     }
     456              : }
     457              : 
     458              : impl PKCS9SigningTime<'_> {
     459              :     /// Time as a tuple: `(year, month, day, hour, min, sec)`
     460          143 :     pub fn time(&self) -> (u64, u64, u64, u64, u64, u64) {
     461          143 :         let vec = Vec::from(self.ptr.time().as_slice());
     462          143 :         if vec.len() != 6 {
     463            0 :             return (0, 0, 0, 0, 0, 0);
     464          143 :         }
     465          143 :         (vec[0], vec[1], vec[2], vec[3], vec[4], vec[5])
     466          143 :     }
     467              : }
     468              : 
     469              : /// Interface over the structure described by the OID `1.3.6.1.4.1.311.2.1.12`
     470              : ///
     471              : /// The internal structure is described in the official document:
     472              : /// *Windows Authenticode Portable Executable Signature Format*
     473              : ///
     474              : /// ```text
     475              : /// SpcSpOpusInfo ::= SEQUENCE {
     476              : ///     programName  [0] EXPLICIT SpcString OPTIONAL,
     477              : ///     moreInfo     [1] EXPLICIT SpcLink OPTIONAL
     478              : /// }
     479              : /// ```
     480              : pub struct SpcSpOpusInfo<'a> {
     481              :     ptr: cxx::UniquePtr<ffi::PE_SpcSpOpusInfo>,
     482              :     _owner: PhantomData<&'a ffi::PE_SignerInfo>,
     483              : }
     484              : 
     485              : impl std::fmt::Debug for SpcSpOpusInfo<'_> {
     486          156 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     487          156 :         f.debug_struct("SpcSpOpusInfo")
     488          156 :             .field("program_name", &self.program_name())
     489          156 :             .field("more_info", &self.more_info())
     490          156 :             .finish()
     491          156 :     }
     492              : }
     493              : 
     494              : impl<'a> FromFFI<ffi::PE_SpcSpOpusInfo> for SpcSpOpusInfo<'a> {
     495          156 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_SpcSpOpusInfo>) -> Self {
     496          156 :         Self {
     497          156 :             ptr,
     498          156 :             _owner: PhantomData,
     499          156 :         }
     500          156 :     }
     501              : }
     502              : 
     503              : impl SpcSpOpusInfo<'_> {
     504              :     /// Program description provided by the publisher
     505          156 :     pub fn program_name(&self) -> String {
     506          156 :         self.ptr.program_name().to_string()
     507          156 :     }
     508              : 
     509              :     /// Other information such as an url
     510          156 :     pub fn more_info(&self) -> String {
     511          156 :         self.ptr.more_info().to_string()
     512          156 :     }
     513              : }
     514              : 
     515              : pub struct SpcRelaxedPeMarkerCheck<'a> {
     516              :     #[allow(dead_code)]
     517              :     ptr: cxx::UniquePtr<ffi::PE_SpcRelaxedPeMarkerCheck>,
     518              :     _owner: PhantomData<&'a ffi::PE_SignerInfo>,
     519              : }
     520              : 
     521              : impl std::fmt::Debug for SpcRelaxedPeMarkerCheck<'_> {
     522            0 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     523            0 :         f.debug_struct("SpcRelaxedPeMarkerCheck").finish()
     524            0 :     }
     525              : }
     526              : 
     527              : impl<'a> FromFFI<ffi::PE_SpcRelaxedPeMarkerCheck> for SpcRelaxedPeMarkerCheck<'a> {
     528           26 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_SpcRelaxedPeMarkerCheck>) -> Self {
     529           26 :         Self {
     530           26 :             ptr,
     531           26 :             _owner: PhantomData,
     532           26 :         }
     533           26 :     }
     534              : }
     535              : 
     536              : impl SpcRelaxedPeMarkerCheck<'_> {}
     537              : 
     538              : /// ```text
     539              : /// SigningCertificateV2 ::= SEQUENCE {
     540              : ///   certs    SEQUENCE OF ESSCertIDv2,
     541              : ///   policies SEQUENCE OF PolicyInformation OPTIONAL
     542              : /// }
     543              : ///
     544              : /// ESSCertIDv2 ::= SEQUENCE {
     545              : ///   hashAlgorithm AlgorithmIdentifier DEFAULT {algorithm id-sha256},
     546              : ///   certHash      OCTET STRING,
     547              : ///   issuerSerial  IssuerSerial OPTIONAL
     548              : /// }
     549              : ///
     550              : /// IssuerSerial ::= SEQUENCE {
     551              : ///   issuer       GeneralNames,
     552              : ///   serialNumber CertificateSerialNumber
     553              : /// }
     554              : ///
     555              : /// PolicyInformation ::= SEQUENCE {
     556              : ///   policyIdentifier   OBJECT IDENTIFIER,
     557              : ///   policyQualifiers   SEQUENCE SIZE (1..MAX) OF PolicyQualifierInfo OPTIONAL
     558              : /// }
     559              : /// ```
     560              : pub struct SigningCertificateV2<'a> {
     561              :     #[allow(dead_code)]
     562              :     ptr: cxx::UniquePtr<ffi::PE_SigningCertificateV2>,
     563              :     _owner: PhantomData<&'a ffi::PE_SignerInfo>,
     564              : }
     565              : 
     566              : impl std::fmt::Debug for SigningCertificateV2<'_> {
     567            0 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     568            0 :         f.debug_struct("SigningCertificateV2").finish()
     569            0 :     }
     570              : }
     571              : 
     572              : impl<'a> FromFFI<ffi::PE_SigningCertificateV2> for SigningCertificateV2<'a> {
     573           78 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_SigningCertificateV2>) -> Self {
     574           78 :         Self {
     575           78 :             ptr,
     576           78 :             _owner: PhantomData,
     577           78 :         }
     578           78 :     }
     579              : }
     580              : 
     581              : impl SigningCertificateV2<'_> {
     582              :     // TODO(romain): Add API
     583              : }
     584              : 
     585              : /// This structure exposes the MS Counter Signature attribute
     586              : pub struct MsCounterSign<'a> {
     587              :     ptr: cxx::UniquePtr<ffi::PE_MsCounterSign>,
     588              :     _owner: PhantomData<&'a ffi::PE_SignerInfo>,
     589              : }
     590              : 
     591              : impl std::fmt::Debug for MsCounterSign<'_> {
     592            0 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     593            0 :         f.debug_struct("MsCounterSign").finish()
     594            0 :     }
     595              : }
     596              : 
     597              : impl<'a> FromFFI<ffi::PE_MsCounterSign> for MsCounterSign<'a> {
     598          117 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_MsCounterSign>) -> Self {
     599          117 :         Self {
     600          117 :             ptr,
     601          117 :             _owner: PhantomData,
     602          117 :         }
     603          117 :     }
     604              : }
     605              : 
     606              : impl<'a> MsCounterSign<'a> {
     607            0 :     pub fn version(&self) -> u32 {
     608            0 :         self.ptr.version()
     609            0 :     }
     610              : 
     611            0 :     pub fn digest_algorithm(&self) -> Algorithms {
     612            0 :         Algorithms::from(self.ptr.digest_algorithm())
     613            0 :     }
     614              : 
     615              :     /// ContentInfo as described in the RFC2315 <https://tools.ietf.org/html/rfc2315#section-7>
     616          234 :     pub fn content_info(&'a self) -> ContentInfo<'a> {
     617          234 :         ContentInfo::from_ffi(self.ptr.content_info())
     618          234 :     }
     619              : 
     620              :     /// Return list of [`crate::pe::signature::X509`] certificates associated with this signature
     621          117 :     pub fn certificates(&'a self) -> MsCounterCertificates<'a> {
     622          117 :         MsCounterCertificates::new(self.ptr.certificates())
     623          117 :     }
     624              : 
     625              :     /// Iterator over the signer [`SignerInfo`] defined in the PKCS #7 signature
     626          117 :     pub fn signers(&'a self) -> MsCounterSigners<'a> {
     627          117 :         MsCounterSigners::new(self.ptr.signers())
     628          117 :     }
     629              : }
     630              : 
     631          208 : declare_iterator!(
     632          208 :     MsCounterCertificates,
     633          208 :     X509<'a>,
     634          208 :     ffi::PE_x509,
     635          208 :     ffi::PE_MsCounterSign,
     636          208 :     ffi::PE_MsCounterSign_it_certificates
     637          208 : );
     638              : 
     639          117 : declare_iterator!(
     640          117 :     MsCounterSigners,
     641          117 :     SignerInfo<'a>,
     642          117 :     ffi::PE_SignerInfo,
     643          117 :     ffi::PE_MsCounterSign,
     644          117 :     ffi::PE_MsCounterSign_it_signers
     645          117 : );
     646              : 
     647              : /// Interface over the structure described by the OID `1.3.6.1.4.1.311.10.3.28` (szOID_PLATFORM_MANIFEST_BINARY_ID)
     648              : ///
     649              : /// The internal structure is not documented but we can infer the following structure:
     650              : ///
     651              : /// ```text
     652              : /// szOID_PLATFORM_MANIFEST_BINARY_ID ::= SET OF BinaryID
     653              : /// ```
     654              : ///
     655              : /// `BinaryID` being an alias of UTF8STRING
     656              : pub struct MsManifestBinaryID<'a> {
     657              :     ptr: cxx::UniquePtr<ffi::PE_MsManifestBinaryID>,
     658              :     _owner: PhantomData<&'a ffi::PE_SignerInfo>,
     659              : }
     660              : 
     661              : impl std::fmt::Debug for MsManifestBinaryID<'_> {
     662            0 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     663            0 :         f.debug_struct("MsManifestBinaryID")
     664            0 :             .field("manifest_id", &self.manifest_id())
     665            0 :             .finish()
     666            0 :     }
     667              : }
     668              : 
     669              : impl<'a> FromFFI<ffi::PE_MsManifestBinaryID> for MsManifestBinaryID<'a> {
     670           13 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_MsManifestBinaryID>) -> Self {
     671           13 :         Self {
     672           13 :             ptr,
     673           13 :             _owner: PhantomData,
     674           13 :         }
     675           13 :     }
     676              : }
     677              : 
     678              : impl MsManifestBinaryID<'_> {
     679           13 :     pub fn manifest_id(&self) -> String {
     680           13 :         self.ptr.manifest_id().to_string()
     681           13 :     }
     682              : }
        

Generated by: LCOV version 2.1-1