LCOV - code coverage report
Current view: top level - src/pe/signature - attributes.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 86.5 % 303 262
Test Date: 2024-10-27:00:00:00 Functions: 80.9 % 47 38

            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::to_slice;
       7              : use crate::pe::Algorithms;
       8              : use crate::pe::signature::ContentInfo;
       9              : use crate::declare_iterator;
      10              : use crate::pe::signature::X509;
      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          816 :     fn from_ffi(ffi_entry: cxx::UniquePtr<ffi::PE_Attribute>) -> Self {
      48          816 :         unsafe {
      49          816 :             let cmd_ref = ffi_entry.as_ref().unwrap();
      50          816 : 
      51          816 :             if ffi::PE_ContentType::classof(cmd_ref) {
      52          192 :                 let raw = {
      53          192 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
      54          192 :                     type To = cxx::UniquePtr<ffi::PE_ContentType>;
      55          192 :                     std::mem::transmute::<From, To>(ffi_entry)
      56          192 :                 };
      57          192 :                 Attribute::ContentType(ContentType::from_ffi(raw))
      58          624 :             } else if ffi::PE_MsSpcNestedSignature::classof(cmd_ref) {
      59           24 :                 let raw = {
      60           24 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
      61           24 :                     type To = cxx::UniquePtr<ffi::PE_MsSpcNestedSignature>;
      62           24 :                     std::mem::transmute::<From, To>(ffi_entry)
      63           24 :                 };
      64           24 :                 Attribute::MsSpcNestedSignature(MsSpcNestedSignature::from_ffi(raw))
      65          600 :             } else if ffi::PE_MsSpcStatementType::classof(cmd_ref) {
      66           88 :                 let raw = {
      67           88 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
      68           88 :                     type To = cxx::UniquePtr<ffi::PE_MsSpcStatementType>;
      69           88 :                     std::mem::transmute::<From, To>(ffi_entry)
      70           88 :                 };
      71           88 :                 Attribute::MsSpcStatementType(MsSpcStatementType::from_ffi(raw))
      72          512 :             } else if ffi::PE_PKCS9AtSequenceNumber::classof(cmd_ref) {
      73           16 :                 let raw = {
      74           16 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
      75           16 :                     type To = cxx::UniquePtr<ffi::PE_PKCS9AtSequenceNumber>;
      76           16 :                     std::mem::transmute::<From, To>(ffi_entry)
      77           16 :                 };
      78           16 :                 Attribute::PKCS9AtSequenceNumber(PKCS9AtSequenceNumber::from_ffi(raw))
      79          496 :             } else if ffi::PE_PKCS9CounterSignature::classof(cmd_ref) {
      80           40 :                 let raw = {
      81           40 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
      82           40 :                     type To = cxx::UniquePtr<ffi::PE_PKCS9CounterSignature>;
      83           40 :                     std::mem::transmute::<From, To>(ffi_entry)
      84           40 :                 };
      85           40 :                 Attribute::PKCS9CounterSignature(PKCS9CounterSignature::from_ffi(raw))
      86          456 :             } else if ffi::PE_PKCS9MessageDigest::classof(cmd_ref) {
      87          192 :                 let raw = {
      88          192 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
      89          192 :                     type To = cxx::UniquePtr<ffi::PE_PKCS9MessageDigest>;
      90          192 :                     std::mem::transmute::<From, To>(ffi_entry)
      91          192 :                 };
      92          192 :                 Attribute::PKCS9MessageDigest(PKCS9MessageDigest::from_ffi(raw))
      93          264 :             } else if ffi::PE_PKCS9SigningTime::classof(cmd_ref) {
      94           88 :                 let raw = {
      95           88 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
      96           88 :                     type To = cxx::UniquePtr<ffi::PE_PKCS9SigningTime>;
      97           88 :                     std::mem::transmute::<From, To>(ffi_entry)
      98           88 :                 };
      99           88 :                 Attribute::PKCS9SigningTime(PKCS9SigningTime::from_ffi(raw))
     100          176 :             } else if ffi::PE_SpcSpOpusInfo::classof(cmd_ref) {
     101           72 :                 let raw = {
     102           72 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
     103           72 :                     type To = cxx::UniquePtr<ffi::PE_SpcSpOpusInfo>;
     104           72 :                     std::mem::transmute::<From, To>(ffi_entry)
     105           72 :                 };
     106           72 :                 Attribute::SpcSpOpusInfo(SpcSpOpusInfo::from_ffi(raw))
     107          104 :             } else if ffi::PE_MsManifestBinaryID::classof(cmd_ref) {
     108            8 :                 let raw = {
     109            8 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
     110            8 :                     type To = cxx::UniquePtr<ffi::PE_MsManifestBinaryID>;
     111            8 :                     std::mem::transmute::<From, To>(ffi_entry)
     112            8 :                 };
     113            8 :                 Attribute::MsManifestBinaryID(MsManifestBinaryID::from_ffi(raw))
     114           96 :             } else if ffi::PE_MsCounterSign::classof(cmd_ref) {
     115           48 :                 let raw = {
     116           48 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
     117           48 :                     type To = cxx::UniquePtr<ffi::PE_MsCounterSign>;
     118           48 :                     std::mem::transmute::<From, To>(ffi_entry)
     119           48 :                 };
     120           48 :                 Attribute::MsCounterSign(MsCounterSign::from_ffi(raw))
     121           48 :             } else if ffi::PE_SpcRelaxedPeMarkerCheck::classof(cmd_ref) {
     122            0 :                 let raw = {
     123            0 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
     124            0 :                     type To = cxx::UniquePtr<ffi::PE_SpcRelaxedPeMarkerCheck>;
     125            0 :                     std::mem::transmute::<From, To>(ffi_entry)
     126            0 :                 };
     127            0 :                 Attribute::SpcRelaxedPeMarkerCheck(SpcRelaxedPeMarkerCheck::from_ffi(raw))
     128           48 :             } else if ffi::PE_SigningCertificateV2::classof(cmd_ref) {
     129           24 :                 let raw = {
     130           24 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
     131           24 :                     type To = cxx::UniquePtr<ffi::PE_SigningCertificateV2>;
     132           24 :                     std::mem::transmute::<From, To>(ffi_entry)
     133           24 :                 };
     134           24 :                 Attribute::SigningCertificateV2(SigningCertificateV2::from_ffi(raw))
     135              :             } else {
     136           24 :                 assert!(
     137           24 :                     ffi::PE_GenericType::classof(cmd_ref),
     138            0 :                     "Must be a GenericType node"
     139              :                 );
     140           24 :                 let raw = {
     141           24 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
     142           24 :                     type To = cxx::UniquePtr<ffi::PE_GenericType>;
     143           24 :                     std::mem::transmute::<From, To>(ffi_entry)
     144           24 :                 };
     145           24 :                 Attribute::GenericType(GenericType::from_ffi(raw))
     146              :             }
     147              :         }
     148          816 :     }
     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          192 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     164          192 :         f.debug_struct("ContentType")
     165          192 :             .field("oid", &self.oid())
     166          192 :             .finish()
     167          192 :     }
     168              : }
     169              : 
     170              : impl<'a> FromFFI<ffi::PE_ContentType> for ContentType<'a> {
     171          192 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_ContentType>) -> Self {
     172          192 :         Self {
     173          192 :             ptr,
     174          192 :             _owner: PhantomData,
     175          192 :         }
     176          192 :     }
     177              : }
     178              : 
     179              : impl ContentType<'_> {
     180              :     /// OID as described in RFC #2985
     181          192 :     pub fn oid(&self) -> String {
     182          192 :         self.ptr.oid().to_string()
     183          192 :     }
     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           24 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     194           24 :         f.debug_struct("GenericType")
     195           24 :             .field("oid", &self.oid())
     196           24 :             .finish()
     197           24 :     }
     198              : }
     199              : 
     200              : impl<'a> FromFFI<ffi::PE_GenericType> for GenericType<'a> {
     201           24 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_GenericType>) -> Self {
     202           24 :         Self {
     203           24 :             ptr,
     204           24 :             _owner: PhantomData,
     205           24 :         }
     206           24 :     }
     207              : }
     208              : 
     209              : impl GenericType<'_> {
     210              :     /// OID of the original attribute
     211           24 :     pub fn oid(&self) -> String {
     212           24 :         self.ptr.oid().to_string()
     213           24 :     }
     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           24 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     237           24 :         f.debug_struct("MsSpcNestedSignature").finish()
     238           24 :     }
     239              : }
     240              : 
     241              : impl<'a> FromFFI<ffi::PE_MsSpcNestedSignature> for MsSpcNestedSignature<'a> {
     242           24 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_MsSpcNestedSignature>) -> Self {
     243           24 :         Self {
     244           24 :             ptr,
     245           24 :             _owner: PhantomData,
     246           24 :         }
     247           24 :     }
     248              : }
     249              : 
     250              : impl MsSpcNestedSignature<'_> {
     251              :     /// Underlying Signature object
     252           24 :     pub fn signature(&self) -> Signature {
     253           24 :         Signature::from_ffi(self.ptr.sig())
     254           24 :     }
     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           88 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     272           88 :         f.debug_struct("MsSpcStatementType")
     273           88 :             .field("oid", &self.oid())
     274           88 :             .finish()
     275           88 :     }
     276              : }
     277              : 
     278              : impl<'a> FromFFI<ffi::PE_MsSpcStatementType> for MsSpcStatementType<'a> {
     279           88 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_MsSpcStatementType>) -> Self {
     280           88 :         Self {
     281           88 :             ptr,
     282           88 :             _owner: PhantomData,
     283           88 :         }
     284           88 :     }
     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           88 :     pub fn oid(&self) -> String {
     293           88 :         self.ptr.oid().to_string()
     294           88 :     }
     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           16 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     319           16 :         f.debug_struct("PKCS9AtSequenceNumber")
     320           16 :             .field("number", &self.number())
     321           16 :             .finish()
     322           16 :     }
     323              : }
     324              : 
     325              : impl PKCS9AtSequenceNumber<'_> {
     326              :     //! Number as described in the RFC
     327           16 :     pub fn number(&self) -> u32 {
     328           16 :         self.ptr.number()
     329           16 :     }
     330              : }
     331              : 
     332              : impl<'a> FromFFI<ffi::PE_PKCS9AtSequenceNumber> for PKCS9AtSequenceNumber<'a> {
     333           16 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_PKCS9AtSequenceNumber>) -> Self {
     334           16 :         Self {
     335           16 :             ptr,
     336           16 :             _owner: PhantomData,
     337           16 :         }
     338           16 :     }
     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           40 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     359           40 :         f.debug_struct("PKCS9CounterSignature").finish()
     360           40 :     }
     361              : }
     362              : 
     363              : impl<'a> FromFFI<ffi::PE_PKCS9CounterSignature> for PKCS9CounterSignature<'a> {
     364           40 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_PKCS9CounterSignature>) -> Self {
     365           40 :         Self {
     366           40 :             ptr,
     367           40 :             _owner: PhantomData,
     368           40 :         }
     369           40 :     }
     370              : }
     371              : 
     372              : impl PKCS9CounterSignature<'_> {
     373              :     /// SignerInfo as described in the RFC #2985
     374           40 :     pub fn signer(&self) -> SignerInfo {
     375           40 :         SignerInfo::from_ffi(self.ptr.signer())
     376           40 :     }
     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          192 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     401          192 :         f.debug_struct("PKCS9MessageDigest").finish()
     402          192 :     }
     403              : }
     404              : 
     405              : impl PKCS9MessageDigest<'_> {
     406              :     /// Message digeset as a blob of bytes as described in the RFC
     407          192 :     pub fn digest(&self) -> &[u8] {
     408          192 :         to_slice!(self.ptr.digest());
     409          192 :     }
     410              : }
     411              : 
     412              : impl<'a> FromFFI<ffi::PE_PKCS9MessageDigest> for PKCS9MessageDigest<'a> {
     413          192 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_PKCS9MessageDigest>) -> Self {
     414          192 :         Self {
     415          192 :             ptr,
     416          192 :             _owner: PhantomData,
     417          192 :         }
     418          192 :     }
     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           88 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     443           88 :         f.debug_struct("PKCS9SigningTime")
     444           88 :             .field("time", &self.time())
     445           88 :             .finish()
     446           88 :     }
     447              : }
     448              : 
     449              : impl<'a> FromFFI<ffi::PE_PKCS9SigningTime> for PKCS9SigningTime<'a> {
     450           88 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_PKCS9SigningTime>) -> Self {
     451           88 :         Self {
     452           88 :             ptr,
     453           88 :             _owner: PhantomData,
     454           88 :         }
     455           88 :     }
     456              : }
     457              : 
     458              : impl PKCS9SigningTime<'_> {
     459              :     /// Time as a tuple: `(year, month, day, hour, min, sec)`
     460           88 :     pub fn time(&self) -> (u64, u64, u64, u64, u64, u64) {
     461           88 :         let vec = Vec::from(self.ptr.time().as_slice());
     462           88 :         if vec.len() != 6 {
     463            0 :             return (0, 0, 0, 0, 0, 0);
     464           88 :         }
     465           88 :         (vec[0], vec[1], vec[2], vec[3], vec[4], vec[5])
     466           88 :     }
     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           72 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     487           72 :         f.debug_struct("SpcSpOpusInfo")
     488           72 :             .field("program_name", &self.program_name())
     489           72 :             .field("more_info", &self.more_info())
     490           72 :             .finish()
     491           72 :     }
     492              : }
     493              : 
     494              : impl<'a> FromFFI<ffi::PE_SpcSpOpusInfo> for SpcSpOpusInfo<'a> {
     495           72 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_SpcSpOpusInfo>) -> Self {
     496           72 :         Self {
     497           72 :             ptr,
     498           72 :             _owner: PhantomData,
     499           72 :         }
     500           72 :     }
     501              : }
     502              : 
     503              : impl SpcSpOpusInfo<'_> {
     504              :     /// Program description provided by the publisher
     505           72 :     pub fn program_name(&self) -> String {
     506           72 :         self.ptr.program_name().to_string()
     507           72 :     }
     508              : 
     509              :     /// Other information such as an url
     510           72 :     pub fn more_info(&self) -> String {
     511           72 :         self.ptr.more_info().to_string()
     512           72 :     }
     513              : }
     514              : 
     515              : pub struct SpcRelaxedPeMarkerCheck<'a> {
     516              :     ptr: cxx::UniquePtr<ffi::PE_SpcRelaxedPeMarkerCheck>,
     517              :     _owner: PhantomData<&'a ffi::PE_SignerInfo>,
     518              : }
     519              : 
     520              : impl std::fmt::Debug for SpcRelaxedPeMarkerCheck<'_> {
     521            0 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     522            0 :         f.debug_struct("SpcRelaxedPeMarkerCheck")
     523            0 :             .finish()
     524            0 :     }
     525              : }
     526              : 
     527              : impl<'a> FromFFI<ffi::PE_SpcRelaxedPeMarkerCheck> for SpcRelaxedPeMarkerCheck<'a> {
     528            0 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_SpcRelaxedPeMarkerCheck>) -> Self {
     529            0 :         Self {
     530            0 :             ptr,
     531            0 :             _owner: PhantomData,
     532            0 :         }
     533            0 :     }
     534              : }
     535              : 
     536              : impl SpcRelaxedPeMarkerCheck<'_> {
     537              : 
     538              : }
     539              : 
     540              : 
     541              : /// ```text
     542              : /// SigningCertificateV2 ::= SEQUENCE {
     543              : ///   certs    SEQUENCE OF ESSCertIDv2,
     544              : ///   policies SEQUENCE OF PolicyInformation OPTIONAL
     545              : /// }
     546              : ///
     547              : /// ESSCertIDv2 ::= SEQUENCE {
     548              : ///   hashAlgorithm AlgorithmIdentifier DEFAULT {algorithm id-sha256},
     549              : ///   certHash      OCTET STRING,
     550              : ///   issuerSerial  IssuerSerial OPTIONAL
     551              : /// }
     552              : ///
     553              : /// IssuerSerial ::= SEQUENCE {
     554              : ///   issuer       GeneralNames,
     555              : ///   serialNumber CertificateSerialNumber
     556              : /// }
     557              : ///
     558              : /// PolicyInformation ::= SEQUENCE {
     559              : ///   policyIdentifier   OBJECT IDENTIFIER,
     560              : ///   policyQualifiers   SEQUENCE SIZE (1..MAX) OF PolicyQualifierInfo OPTIONAL
     561              : /// }
     562              : /// ```
     563              : pub struct SigningCertificateV2<'a> {
     564              :     ptr: cxx::UniquePtr<ffi::PE_SigningCertificateV2>,
     565              :     _owner: PhantomData<&'a ffi::PE_SignerInfo>,
     566              : }
     567              : 
     568              : impl std::fmt::Debug for SigningCertificateV2<'_> {
     569            0 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     570            0 :         f.debug_struct("SigningCertificateV2")
     571            0 :             .finish()
     572            0 :     }
     573              : }
     574              : 
     575              : impl<'a> FromFFI<ffi::PE_SigningCertificateV2> for SigningCertificateV2<'a> {
     576           24 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_SigningCertificateV2>) -> Self {
     577           24 :         Self {
     578           24 :             ptr,
     579           24 :             _owner: PhantomData,
     580           24 :         }
     581           24 :     }
     582              : }
     583              : 
     584              : impl SigningCertificateV2<'_> {
     585              :     // TODO(romain): Add API
     586              : }
     587              : 
     588              : /// This structure exposes the MS Counter Signature attribute
     589              : pub struct MsCounterSign<'a> {
     590              :     ptr: cxx::UniquePtr<ffi::PE_MsCounterSign>,
     591              :     _owner: PhantomData<&'a ffi::PE_SignerInfo>,
     592              : }
     593              : 
     594              : impl std::fmt::Debug for MsCounterSign<'_> {
     595            0 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     596            0 :         f.debug_struct("MsCounterSign")
     597            0 :             .finish()
     598            0 :     }
     599              : }
     600              : 
     601              : impl<'a> FromFFI<ffi::PE_MsCounterSign> for MsCounterSign<'a> {
     602           48 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_MsCounterSign>) -> Self {
     603           48 :         Self {
     604           48 :             ptr,
     605           48 :             _owner: PhantomData,
     606           48 :         }
     607           48 :     }
     608              : }
     609              : 
     610              : impl<'a> MsCounterSign<'a> {
     611            0 :     pub fn version(&self) -> u32 {
     612            0 :         self.ptr.version()
     613            0 :     }
     614              : 
     615            0 :     pub fn digest_algorithm(&self) -> Algorithms {
     616            0 :         Algorithms::from(self.ptr.digest_algorithm())
     617            0 :     }
     618              : 
     619              :     /// ContentInfo as described in the RFC2315 <https://tools.ietf.org/html/rfc2315#section-7>
     620           96 :     pub fn content_info(&'a self) -> ContentInfo<'a> {
     621           96 :         ContentInfo::from_ffi(self.ptr.content_info())
     622           96 :     }
     623              : 
     624              :     /// Return list of [`crate::pe::X509`] certificates associated with this signature
     625           48 :     pub fn certificates(&'a self) -> MsCounterCertificates<'a> {
     626           48 :         MsCounterCertificates::new(self.ptr.certificates())
     627           48 :     }
     628              : 
     629              :     /// Iterator over the signer [`SignerInfo`] defined in the PKCS #7 signature
     630           48 :     pub fn signers(&'a self) -> MsCounterSigners<'a> {
     631           48 :         MsCounterSigners::new(self.ptr.signers())
     632           48 :     }
     633              : }
     634              : 
     635           80 : declare_iterator!(
     636           80 :     MsCounterCertificates,
     637           80 :     X509<'a>,
     638           80 :     ffi::PE_x509,
     639           80 :     ffi::PE_MsCounterSign,
     640           80 :     ffi::PE_MsCounterSign_it_certificates
     641           80 : );
     642              : 
     643           48 : declare_iterator!(
     644           48 :     MsCounterSigners,
     645           48 :     SignerInfo<'a>,
     646           48 :     ffi::PE_SignerInfo,
     647           48 :     ffi::PE_MsCounterSign,
     648           48 :     ffi::PE_MsCounterSign_it_signers
     649           48 : );
     650              : 
     651              : /// Interface over the structure described by the OID `1.3.6.1.4.1.311.10.3.28` (szOID_PLATFORM_MANIFEST_BINARY_ID)
     652              : ///
     653              : /// The internal structure is not documented but we can infer the following structure:
     654              : ///
     655              : /// ```text
     656              : /// szOID_PLATFORM_MANIFEST_BINARY_ID ::= SET OF BinaryID
     657              : /// ```
     658              : ///
     659              : /// `BinaryID` being an alias of UTF8STRING
     660              : pub struct MsManifestBinaryID<'a> {
     661              :     ptr: cxx::UniquePtr<ffi::PE_MsManifestBinaryID>,
     662              :     _owner: PhantomData<&'a ffi::PE_SignerInfo>,
     663              : }
     664              : 
     665              : impl std::fmt::Debug for MsManifestBinaryID<'_> {
     666            0 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     667            0 :         f.debug_struct("MsManifestBinaryID")
     668            0 :             .field("manifest_id", &self.manifest_id())
     669            0 :             .finish()
     670            0 :     }
     671              : }
     672              : 
     673              : impl<'a> FromFFI<ffi::PE_MsManifestBinaryID> for MsManifestBinaryID<'a> {
     674            8 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_MsManifestBinaryID>) -> Self {
     675            8 :         Self {
     676            8 :             ptr,
     677            8 :             _owner: PhantomData,
     678            8 :         }
     679            8 :     }
     680              : }
     681              : 
     682              : impl MsManifestBinaryID<'_> {
     683            8 :     pub fn manifest_id(&self) -> String {
     684            8 :         self.ptr.manifest_id().to_string()
     685            8 :     }
     686              : }
        

Generated by: LCOV version 2.1-1