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-10-27: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          152 :     pub fn content_type(&self) -> String {
      19          152 :         self.ptr.content_type().to_string()
      20          152 :     }
      21              : 
      22          152 :     pub fn value(&self) -> Option<Content<'_>> {
      23          152 :         into_optional(self.ptr.value())
      24          152 :     }
      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          152 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
      40          152 :         f.debug_struct("ContentInfo")
      41          152 :             .field("content_type", &self.content_type())
      42          152 :             .finish()
      43          152 :     }
      44              : }
      45              : 
      46              : impl<'a> FromFFI<ffi::PE_ContentInfo> for ContentInfo<'a> {
      47          304 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_ContentInfo>) -> Self {
      48          304 :         ContentInfo {
      49          304 :             ptr,
      50          304 :             _owner: PhantomData,
      51          304 :         }
      52          304 :     }
      53              : }
      54              : 
      55          152 : #[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          152 :     fn from_ffi(ffi_entry: cxx::UniquePtr<ffi::PE_ContentInfo_Content>) -> Self {
      64          152 :         unsafe {
      65          152 :             let content_ref = ffi_entry.as_ref().unwrap();
      66          152 :             if ffi::PE_SpcIndirectData::classof(content_ref) {
      67          104 :                 let raw = {
      68          104 :                     type From = cxx::UniquePtr<ffi::PE_ContentInfo_Content>;
      69          104 :                     type To = cxx::UniquePtr<ffi::PE_SpcIndirectData>;
      70          104 :                     std::mem::transmute::<From, To>(ffi_entry)
      71          104 :                 };
      72          104 :                 Content::SpcIndirectData(SpcIndirectData::from_ffi(raw))
      73              :             }
      74           48 :             else if ffi::PE_PKCS9TSTInfo::classof(content_ref) {
      75           48 :                 let raw = {
      76           48 :                     type From = cxx::UniquePtr<ffi::PE_ContentInfo_Content>;
      77           48 :                     type To = cxx::UniquePtr<ffi::PE_PKCS9TSTInfo>;
      78           48 :                     std::mem::transmute::<From, To>(ffi_entry)
      79           48 :                 };
      80           48 :                 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          152 :     }
      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          208 :     pub fn file(&self) -> String {
     111          208 :         self.ptr.file().to_string()
     112          208 :     }
     113              :     /// PE's authentihash
     114              :     ///
     115              :     /// See: [`crate::pe::Binary::authentihash`]
     116          104 :     pub fn digest(&self) -> &[u8] {
     117          104 :         to_slice!(self.ptr.digest());
     118          104 :     }
     119              : 
     120              :     /// Digest used to hash the file
     121          208 :     pub fn digest_algorithm(&self) -> Algorithms {
     122          208 :         Algorithms::from(self.ptr.digest_algorithm())
     123          208 :     }
     124              : }
     125              : 
     126              : impl std::fmt::Debug for SpcIndirectData<'_> {
     127          208 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     128          208 :         f.debug_struct("SpcIndirectData")
     129          208 :             .field("file", &self.file())
     130          208 :             .field("digest_algorithm", &self.digest_algorithm())
     131          208 :             .finish()
     132          208 :     }
     133              : }
     134              : 
     135              : impl FromFFI<ffi::PE_SpcIndirectData> for SpcIndirectData<'_> {
     136          104 :     fn from_ffi(cmd: cxx::UniquePtr<ffi::PE_SpcIndirectData>) -> Self {
     137          104 :         Self {
     138          104 :             ptr: cmd,
     139          104 :             _owner: PhantomData,
     140          104 :         }
     141          104 :     }
     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           48 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
     161           48 :         f.debug_struct("PKCS9TSTInfo")
     162           48 :             .finish()
     163           48 :     }
     164              : }
     165              : 
     166              : impl FromFFI<ffi::PE_PKCS9TSTInfo> for PKCS9TSTInfo<'_> {
     167           48 :     fn from_ffi(cmd: cxx::UniquePtr<ffi::PE_PKCS9TSTInfo>) -> Self {
     168           48 :         Self {
     169           48 :             ptr: cmd,
     170           48 :             _owner: PhantomData,
     171           48 :         }
     172           48 :     }
     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