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-11-30: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         1020 :     fn from_ffi(ffi_entry: cxx::UniquePtr<ffi::PE_Attribute>) -> Self {
      48         1020 :         unsafe {
      49         1020 :             let cmd_ref = ffi_entry.as_ref().unwrap();
      50         1020 : 
      51         1020 :             if ffi::PE_ContentType::classof(cmd_ref) {
      52          240 :                 let raw = {
      53          240 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
      54          240 :                     type To = cxx::UniquePtr<ffi::PE_ContentType>;
      55          240 :                     std::mem::transmute::<From, To>(ffi_entry)
      56          240 :                 };
      57          240 :                 Attribute::ContentType(ContentType::from_ffi(raw))
      58          780 :             } else if ffi::PE_MsSpcNestedSignature::classof(cmd_ref) {
      59           30 :                 let raw = {
      60           30 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
      61           30 :                     type To = cxx::UniquePtr<ffi::PE_MsSpcNestedSignature>;
      62           30 :                     std::mem::transmute::<From, To>(ffi_entry)
      63           30 :                 };
      64           30 :                 Attribute::MsSpcNestedSignature(MsSpcNestedSignature::from_ffi(raw))
      65          750 :             } else if ffi::PE_MsSpcStatementType::classof(cmd_ref) {
      66          110 :                 let raw = {
      67          110 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
      68          110 :                     type To = cxx::UniquePtr<ffi::PE_MsSpcStatementType>;
      69          110 :                     std::mem::transmute::<From, To>(ffi_entry)
      70          110 :                 };
      71          110 :                 Attribute::MsSpcStatementType(MsSpcStatementType::from_ffi(raw))
      72          640 :             } else if ffi::PE_PKCS9AtSequenceNumber::classof(cmd_ref) {
      73           20 :                 let raw = {
      74           20 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
      75           20 :                     type To = cxx::UniquePtr<ffi::PE_PKCS9AtSequenceNumber>;
      76           20 :                     std::mem::transmute::<From, To>(ffi_entry)
      77           20 :                 };
      78           20 :                 Attribute::PKCS9AtSequenceNumber(PKCS9AtSequenceNumber::from_ffi(raw))
      79          620 :             } else if ffi::PE_PKCS9CounterSignature::classof(cmd_ref) {
      80           50 :                 let raw = {
      81           50 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
      82           50 :                     type To = cxx::UniquePtr<ffi::PE_PKCS9CounterSignature>;
      83           50 :                     std::mem::transmute::<From, To>(ffi_entry)
      84           50 :                 };
      85           50 :                 Attribute::PKCS9CounterSignature(PKCS9CounterSignature::from_ffi(raw))
      86          570 :             } else if ffi::PE_PKCS9MessageDigest::classof(cmd_ref) {
      87          240 :                 let raw = {
      88          240 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
      89          240 :                     type To = cxx::UniquePtr<ffi::PE_PKCS9MessageDigest>;
      90          240 :                     std::mem::transmute::<From, To>(ffi_entry)
      91          240 :                 };
      92          240 :                 Attribute::PKCS9MessageDigest(PKCS9MessageDigest::from_ffi(raw))
      93          330 :             } else if ffi::PE_PKCS9SigningTime::classof(cmd_ref) {
      94          110 :                 let raw = {
      95          110 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
      96          110 :                     type To = cxx::UniquePtr<ffi::PE_PKCS9SigningTime>;
      97          110 :                     std::mem::transmute::<From, To>(ffi_entry)
      98          110 :                 };
      99          110 :                 Attribute::PKCS9SigningTime(PKCS9SigningTime::from_ffi(raw))
     100          220 :             } else if ffi::PE_SpcSpOpusInfo::classof(cmd_ref) {
     101           90 :                 let raw = {
     102           90 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
     103           90 :                     type To = cxx::UniquePtr<ffi::PE_SpcSpOpusInfo>;
     104           90 :                     std::mem::transmute::<From, To>(ffi_entry)
     105           90 :                 };
     106           90 :                 Attribute::SpcSpOpusInfo(SpcSpOpusInfo::from_ffi(raw))
     107          130 :             } else if ffi::PE_MsManifestBinaryID::classof(cmd_ref) {
     108           10 :                 let raw = {
     109           10 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
     110           10 :                     type To = cxx::UniquePtr<ffi::PE_MsManifestBinaryID>;
     111           10 :                     std::mem::transmute::<From, To>(ffi_entry)
     112           10 :                 };
     113           10 :                 Attribute::MsManifestBinaryID(MsManifestBinaryID::from_ffi(raw))
     114          120 :             } else if ffi::PE_MsCounterSign::classof(cmd_ref) {
     115           60 :                 let raw = {
     116           60 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
     117           60 :                     type To = cxx::UniquePtr<ffi::PE_MsCounterSign>;
     118           60 :                     std::mem::transmute::<From, To>(ffi_entry)
     119           60 :                 };
     120           60 :                 Attribute::MsCounterSign(MsCounterSign::from_ffi(raw))
     121           60 :             } 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           60 :             } else if ffi::PE_SigningCertificateV2::classof(cmd_ref) {
     129           30 :                 let raw = {
     130           30 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
     131           30 :                     type To = cxx::UniquePtr<ffi::PE_SigningCertificateV2>;
     132           30 :                     std::mem::transmute::<From, To>(ffi_entry)
     133           30 :                 };
     134           30 :                 Attribute::SigningCertificateV2(SigningCertificateV2::from_ffi(raw))
     135              :             } else {
     136           30 :                 assert!(
     137           30 :                     ffi::PE_GenericType::classof(cmd_ref),
     138            0 :                     "Must be a GenericType node"
     139              :                 );
     140           30 :                 let raw = {
     141           30 :                     type From = cxx::UniquePtr<ffi::PE_Attribute>;
     142           30 :                     type To = cxx::UniquePtr<ffi::PE_GenericType>;
     143           30 :                     std::mem::transmute::<From, To>(ffi_entry)
     144           30 :                 };
     145           30 :                 Attribute::GenericType(GenericType::from_ffi(raw))
     146              :             }
     147              :         }
     148         1020 :     }
     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          240 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     164          240 :         f.debug_struct("ContentType")
     165          240 :             .field("oid", &self.oid())
     166          240 :             .finish()
     167          240 :     }
     168              : }
     169              : 
     170              : impl<'a> FromFFI<ffi::PE_ContentType> for ContentType<'a> {
     171          240 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_ContentType>) -> Self {
     172          240 :         Self {
     173          240 :             ptr,
     174          240 :             _owner: PhantomData,
     175          240 :         }
     176          240 :     }
     177              : }
     178              : 
     179              : impl ContentType<'_> {
     180              :     /// OID as described in RFC #2985
     181          240 :     pub fn oid(&self) -> String {
     182          240 :         self.ptr.oid().to_string()
     183          240 :     }
     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           30 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     194           30 :         f.debug_struct("GenericType")
     195           30 :             .field("oid", &self.oid())
     196           30 :             .finish()
     197           30 :     }
     198              : }
     199              : 
     200              : impl<'a> FromFFI<ffi::PE_GenericType> for GenericType<'a> {
     201           30 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_GenericType>) -> Self {
     202           30 :         Self {
     203           30 :             ptr,
     204           30 :             _owner: PhantomData,
     205           30 :         }
     206           30 :     }
     207              : }
     208              : 
     209              : impl GenericType<'_> {
     210              :     /// OID of the original attribute
     211           30 :     pub fn oid(&self) -> String {
     212           30 :         self.ptr.oid().to_string()
     213           30 :     }
     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           30 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     237           30 :         f.debug_struct("MsSpcNestedSignature").finish()
     238           30 :     }
     239              : }
     240              : 
     241              : impl<'a> FromFFI<ffi::PE_MsSpcNestedSignature> for MsSpcNestedSignature<'a> {
     242           30 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_MsSpcNestedSignature>) -> Self {
     243           30 :         Self {
     244           30 :             ptr,
     245           30 :             _owner: PhantomData,
     246           30 :         }
     247           30 :     }
     248              : }
     249              : 
     250              : impl MsSpcNestedSignature<'_> {
     251              :     /// Underlying Signature object
     252           30 :     pub fn signature(&self) -> Signature {
     253           30 :         Signature::from_ffi(self.ptr.sig())
     254           30 :     }
     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          110 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     272          110 :         f.debug_struct("MsSpcStatementType")
     273          110 :             .field("oid", &self.oid())
     274          110 :             .finish()
     275          110 :     }
     276              : }
     277              : 
     278              : impl<'a> FromFFI<ffi::PE_MsSpcStatementType> for MsSpcStatementType<'a> {
     279          110 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_MsSpcStatementType>) -> Self {
     280          110 :         Self {
     281          110 :             ptr,
     282          110 :             _owner: PhantomData,
     283          110 :         }
     284          110 :     }
     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          110 :     pub fn oid(&self) -> String {
     293          110 :         self.ptr.oid().to_string()
     294          110 :     }
     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           20 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     319           20 :         f.debug_struct("PKCS9AtSequenceNumber")
     320           20 :             .field("number", &self.number())
     321           20 :             .finish()
     322           20 :     }
     323              : }
     324              : 
     325              : impl PKCS9AtSequenceNumber<'_> {
     326              :     //! Number as described in the RFC
     327           20 :     pub fn number(&self) -> u32 {
     328           20 :         self.ptr.number()
     329           20 :     }
     330              : }
     331              : 
     332              : impl<'a> FromFFI<ffi::PE_PKCS9AtSequenceNumber> for PKCS9AtSequenceNumber<'a> {
     333           20 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_PKCS9AtSequenceNumber>) -> Self {
     334           20 :         Self {
     335           20 :             ptr,
     336           20 :             _owner: PhantomData,
     337           20 :         }
     338           20 :     }
     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           50 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     359           50 :         f.debug_struct("PKCS9CounterSignature").finish()
     360           50 :     }
     361              : }
     362              : 
     363              : impl<'a> FromFFI<ffi::PE_PKCS9CounterSignature> for PKCS9CounterSignature<'a> {
     364           50 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_PKCS9CounterSignature>) -> Self {
     365           50 :         Self {
     366           50 :             ptr,
     367           50 :             _owner: PhantomData,
     368           50 :         }
     369           50 :     }
     370              : }
     371              : 
     372              : impl PKCS9CounterSignature<'_> {
     373              :     /// SignerInfo as described in the RFC #2985
     374           50 :     pub fn signer(&self) -> SignerInfo {
     375           50 :         SignerInfo::from_ffi(self.ptr.signer())
     376           50 :     }
     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          240 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     401          240 :         f.debug_struct("PKCS9MessageDigest").finish()
     402          240 :     }
     403              : }
     404              : 
     405              : impl PKCS9MessageDigest<'_> {
     406              :     /// Message digeset as a blob of bytes as described in the RFC
     407          240 :     pub fn digest(&self) -> &[u8] {
     408          240 :         to_slice!(self.ptr.digest());
     409          240 :     }
     410              : }
     411              : 
     412              : impl<'a> FromFFI<ffi::PE_PKCS9MessageDigest> for PKCS9MessageDigest<'a> {
     413          240 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_PKCS9MessageDigest>) -> Self {
     414          240 :         Self {
     415          240 :             ptr,
     416          240 :             _owner: PhantomData,
     417          240 :         }
     418          240 :     }
     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          110 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     443          110 :         f.debug_struct("PKCS9SigningTime")
     444          110 :             .field("time", &self.time())
     445          110 :             .finish()
     446          110 :     }
     447              : }
     448              : 
     449              : impl<'a> FromFFI<ffi::PE_PKCS9SigningTime> for PKCS9SigningTime<'a> {
     450          110 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_PKCS9SigningTime>) -> Self {
     451          110 :         Self {
     452          110 :             ptr,
     453          110 :             _owner: PhantomData,
     454          110 :         }
     455          110 :     }
     456              : }
     457              : 
     458              : impl PKCS9SigningTime<'_> {
     459              :     /// Time as a tuple: `(year, month, day, hour, min, sec)`
     460          110 :     pub fn time(&self) -> (u64, u64, u64, u64, u64, u64) {
     461          110 :         let vec = Vec::from(self.ptr.time().as_slice());
     462          110 :         if vec.len() != 6 {
     463            0 :             return (0, 0, 0, 0, 0, 0);
     464          110 :         }
     465          110 :         (vec[0], vec[1], vec[2], vec[3], vec[4], vec[5])
     466          110 :     }
     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           90 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     487           90 :         f.debug_struct("SpcSpOpusInfo")
     488           90 :             .field("program_name", &self.program_name())
     489           90 :             .field("more_info", &self.more_info())
     490           90 :             .finish()
     491           90 :     }
     492              : }
     493              : 
     494              : impl<'a> FromFFI<ffi::PE_SpcSpOpusInfo> for SpcSpOpusInfo<'a> {
     495           90 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_SpcSpOpusInfo>) -> Self {
     496           90 :         Self {
     497           90 :             ptr,
     498           90 :             _owner: PhantomData,
     499           90 :         }
     500           90 :     }
     501              : }
     502              : 
     503              : impl SpcSpOpusInfo<'_> {
     504              :     /// Program description provided by the publisher
     505           90 :     pub fn program_name(&self) -> String {
     506           90 :         self.ptr.program_name().to_string()
     507           90 :     }
     508              : 
     509              :     /// Other information such as an url
     510           90 :     pub fn more_info(&self) -> String {
     511           90 :         self.ptr.more_info().to_string()
     512           90 :     }
     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           30 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_SigningCertificateV2>) -> Self {
     577           30 :         Self {
     578           30 :             ptr,
     579           30 :             _owner: PhantomData,
     580           30 :         }
     581           30 :     }
     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           60 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_MsCounterSign>) -> Self {
     603           60 :         Self {
     604           60 :             ptr,
     605           60 :             _owner: PhantomData,
     606           60 :         }
     607           60 :     }
     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          120 :     pub fn content_info(&'a self) -> ContentInfo<'a> {
     621          120 :         ContentInfo::from_ffi(self.ptr.content_info())
     622          120 :     }
     623              : 
     624              :     /// Return list of [`crate::pe::signature::X509`] certificates associated with this signature
     625           60 :     pub fn certificates(&'a self) -> MsCounterCertificates<'a> {
     626           60 :         MsCounterCertificates::new(self.ptr.certificates())
     627           60 :     }
     628              : 
     629              :     /// Iterator over the signer [`SignerInfo`] defined in the PKCS #7 signature
     630           60 :     pub fn signers(&'a self) -> MsCounterSigners<'a> {
     631           60 :         MsCounterSigners::new(self.ptr.signers())
     632           60 :     }
     633              : }
     634              : 
     635          100 : declare_iterator!(
     636          100 :     MsCounterCertificates,
     637          100 :     X509<'a>,
     638          100 :     ffi::PE_x509,
     639          100 :     ffi::PE_MsCounterSign,
     640          100 :     ffi::PE_MsCounterSign_it_certificates
     641          100 : );
     642              : 
     643           60 : declare_iterator!(
     644           60 :     MsCounterSigners,
     645           60 :     SignerInfo<'a>,
     646           60 :     ffi::PE_SignerInfo,
     647           60 :     ffi::PE_MsCounterSign,
     648           60 :     ffi::PE_MsCounterSign_it_signers
     649           60 : );
     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           10 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_MsManifestBinaryID>) -> Self {
     675           10 :         Self {
     676           10 :             ptr,
     677           10 :             _owner: PhantomData,
     678           10 :         }
     679           10 :     }
     680              : }
     681              : 
     682              : impl MsManifestBinaryID<'_> {
     683           10 :     pub fn manifest_id(&self) -> String {
     684           10 :         self.ptr.manifest_id().to_string()
     685           10 :     }
     686              : }
        

Generated by: LCOV version 2.1-1