LCOV - code coverage report
Current view: top level - src/pe/signature - content_info.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 63.2 % 106 67
Test Date: 2024-11-30:00:00:00 Functions: 56.5 % 23 13

            Line data    Source code
       1              : use std::marker::PhantomData;
       2              : 
       3              : use lief_ffi as ffi;
       4              : 
       5              : use crate::common::{FromFFI, into_optional};
       6              : use crate::to_slice;
       7              : use crate::pe::Algorithms;
       8              : 
       9              : pub struct ContentInfo<'a> {
      10              :     ptr: cxx::UniquePtr<ffi::PE_ContentInfo>,
      11              :     _owner: PhantomData<&'a ffi::PE_Signature>,
      12              : }
      13              : 
      14              : /// ContentInfo as described in the RFC2315 <https://tools.ietf.org/html/rfc2315#section-7>
      15              : impl ContentInfo<'_> {
      16              :     /// Return the OID that describes the content wrapped by this object.
      17              :     /// It should match `SPC_INDIRECT_DATA_OBJID` (`1.3.6.1.4.1.311.2.1.4`)
      18          190 :     pub fn content_type(&self) -> String {
      19          190 :         self.ptr.content_type().to_string()
      20          190 :     }
      21              : 
      22          190 :     pub fn value(&self) -> Option<Content<'_>> {
      23          190 :         into_optional(self.ptr.value())
      24          190 :     }
      25              : 
      26              :     /// Return the digest (authentihash) if the underlying content type is `SPC_INDIRECT_DATA_OBJID`
      27              :     /// Otherwise, return an empty vector
      28            0 :     pub fn digest(&self) -> Vec<u8> {
      29            0 :         Vec::from(self.ptr.digest().as_slice())
      30            0 :     }
      31              : 
      32              :     /// Return the digest used to hash the file
      33            0 :     pub fn digest_algorithm(&self) -> Algorithms {
      34            0 :         Algorithms::from(self.ptr.digest_algorithm())
      35            0 :     }
      36              : }
      37              : 
      38              : impl std::fmt::Debug for ContentInfo<'_> {
      39          190 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
      40          190 :         f.debug_struct("ContentInfo")
      41          190 :             .field("content_type", &self.content_type())
      42          190 :             .finish()
      43          190 :     }
      44              : }
      45              : 
      46              : impl<'a> FromFFI<ffi::PE_ContentInfo> for ContentInfo<'a> {
      47          380 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_ContentInfo>) -> Self {
      48          380 :         ContentInfo {
      49          380 :             ptr,
      50          380 :             _owner: PhantomData,
      51          380 :         }
      52          380 :     }
      53              : }
      54              : 
      55          190 : #[derive(Debug)]
      56              : pub enum Content<'a> {
      57              :     SpcIndirectData(SpcIndirectData<'a>),
      58              :     PKCS9TSTInfo(PKCS9TSTInfo<'a>),
      59              :     Generic(Generic<'a>),
      60              : }
      61              : 
      62              : impl<'a> FromFFI<ffi::PE_ContentInfo_Content> for Content<'a> {
      63          190 :     fn from_ffi(ffi_entry: cxx::UniquePtr<ffi::PE_ContentInfo_Content>) -> Self {
      64          190 :         unsafe {
      65          190 :             let content_ref = ffi_entry.as_ref().unwrap();
      66          190 :             if ffi::PE_SpcIndirectData::classof(content_ref) {
      67          130 :                 let raw = {
      68          130 :                     type From = cxx::UniquePtr<ffi::PE_ContentInfo_Content>;
      69          130 :                     type To = cxx::UniquePtr<ffi::PE_SpcIndirectData>;
      70          130 :                     std::mem::transmute::<From, To>(ffi_entry)
      71          130 :                 };
      72          130 :                 Content::SpcIndirectData(SpcIndirectData::from_ffi(raw))
      73              :             }
      74           60 :             else if ffi::PE_PKCS9TSTInfo::classof(content_ref) {
      75           60 :                 let raw = {
      76           60 :                     type From = cxx::UniquePtr<ffi::PE_ContentInfo_Content>;
      77           60 :                     type To = cxx::UniquePtr<ffi::PE_PKCS9TSTInfo>;
      78           60 :                     std::mem::transmute::<From, To>(ffi_entry)
      79           60 :                 };
      80           60 :                 Content::PKCS9TSTInfo(PKCS9TSTInfo::from_ffi(raw))
      81              :             } else {
      82            0 :                 let raw = {
      83            0 :                     type From = cxx::UniquePtr<ffi::PE_ContentInfo_Content>;
      84            0 :                     type To = cxx::UniquePtr<ffi::PE_GenericContent>;
      85            0 :                     std::mem::transmute::<From, To>(ffi_entry)
      86            0 :                 };
      87            0 :                 Content::Generic(Generic::from_ffi(raw))
      88              :             }
      89              :         }
      90          190 :     }
      91              : }
      92              : 
      93              : pub trait ContentTrait {
      94              :     #[doc(hidden)]
      95              :     fn as_generic(&self) -> &ffi::PE_ContentInfo_Content;
      96              : 
      97              :     /// Return the OID that describes this content info.
      98              :     /// In the case of the PE authenticode, it should return `SPC_INDIRECT_DATA_OBJID (1.3.6.1.4.1.311.2.1.4)`
      99            0 :     fn content_type(&self) -> String {
     100            0 :         self.as_generic().content_type().to_string()
     101            0 :     }
     102              : }
     103              : 
     104              : pub struct SpcIndirectData<'a> {
     105              :     ptr: cxx::UniquePtr<ffi::PE_SpcIndirectData>,
     106              :     _owner: PhantomData<&'a ffi::PE_ContentInfo>,
     107              : }
     108              : 
     109              : impl SpcIndirectData<'_> {
     110          260 :     pub fn file(&self) -> String {
     111          260 :         self.ptr.file().to_string()
     112          260 :     }
     113              :     /// PE's authentihash
     114              :     ///
     115              :     /// See: [`crate::pe::Binary::authentihash`]
     116          130 :     pub fn digest(&self) -> &[u8] {
     117          130 :         to_slice!(self.ptr.digest());
     118          130 :     }
     119              : 
     120              :     /// Digest used to hash the file
     121          260 :     pub fn digest_algorithm(&self) -> Algorithms {
     122          260 :         Algorithms::from(self.ptr.digest_algorithm())
     123          260 :     }
     124              : }
     125              : 
     126              : impl std::fmt::Debug for SpcIndirectData<'_> {
     127          260 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     128          260 :         f.debug_struct("SpcIndirectData")
     129          260 :             .field("file", &self.file())
     130          260 :             .field("digest_algorithm", &self.digest_algorithm())
     131          260 :             .finish()
     132          260 :     }
     133              : }
     134              : 
     135              : impl FromFFI<ffi::PE_SpcIndirectData> for SpcIndirectData<'_> {
     136          130 :     fn from_ffi(cmd: cxx::UniquePtr<ffi::PE_SpcIndirectData>) -> Self {
     137          130 :         Self {
     138          130 :             ptr: cmd,
     139          130 :             _owner: PhantomData,
     140          130 :         }
     141          130 :     }
     142              : }
     143              : 
     144              : impl ContentTrait for SpcIndirectData<'_> {
     145            0 :     fn as_generic(&self) -> &ffi::PE_ContentInfo_Content {
     146            0 :         self.ptr.as_ref().unwrap().as_ref()
     147            0 :     }
     148              : }
     149              : 
     150              : pub struct PKCS9TSTInfo<'a> {
     151              :     ptr: cxx::UniquePtr<ffi::PE_PKCS9TSTInfo>,
     152              :     _owner: PhantomData<&'a ffi::PE_ContentInfo>,
     153              : }
     154              : 
     155              : impl PKCS9TSTInfo<'_> {
     156              :     // TODO(romain): Add API
     157              : }
     158              : 
     159              : impl std::fmt::Debug for PKCS9TSTInfo<'_> {
     160           60 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     161           60 :         f.debug_struct("PKCS9TSTInfo")
     162           60 :             .finish()
     163           60 :     }
     164              : }
     165              : 
     166              : impl FromFFI<ffi::PE_PKCS9TSTInfo> for PKCS9TSTInfo<'_> {
     167           60 :     fn from_ffi(cmd: cxx::UniquePtr<ffi::PE_PKCS9TSTInfo>) -> Self {
     168           60 :         Self {
     169           60 :             ptr: cmd,
     170           60 :             _owner: PhantomData,
     171           60 :         }
     172           60 :     }
     173              : }
     174              : 
     175              : impl ContentTrait for PKCS9TSTInfo<'_> {
     176            0 :     fn as_generic(&self) -> &ffi::PE_ContentInfo_Content {
     177            0 :         self.ptr.as_ref().unwrap().as_ref()
     178            0 :     }
     179              : }
     180              : 
     181              : 
     182              : pub struct Generic<'a> {
     183              :     ptr: cxx::UniquePtr<ffi::PE_GenericContent>,
     184              :     _owner: PhantomData<&'a ffi::PE_ContentInfo>,
     185              : }
     186              : 
     187              : impl Generic<'_> {
     188            0 :     pub fn raw(&self) -> &[u8] {
     189            0 :         to_slice!(self.ptr.raw());
     190            0 :     }
     191              : 
     192            0 :     pub fn oid(&self) -> String {
     193            0 :         self.ptr.oid().to_string()
     194            0 :     }
     195              : 
     196              : }
     197              : 
     198              : impl std::fmt::Debug for Generic<'_> {
     199            0 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     200            0 :         f.debug_struct("Generic").finish()
     201            0 :     }
     202              : }
     203              : 
     204              : impl FromFFI<ffi::PE_GenericContent> for Generic<'_> {
     205            0 :     fn from_ffi(cmd: cxx::UniquePtr<ffi::PE_GenericContent>) -> Self {
     206            0 :         Self {
     207            0 :             ptr: cmd,
     208            0 :             _owner: PhantomData,
     209            0 :         }
     210            0 :     }
     211              : }
     212              : 
     213              : impl ContentTrait for Generic<'_> {
     214            0 :     fn as_generic(&self) -> &ffi::PE_ContentInfo_Content {
     215            0 :         self.ptr.as_ref().unwrap().as_ref()
     216            0 :     }
     217              : }
     218              : 
        

Generated by: LCOV version 2.1-1