LCOV - code coverage report
Current view: top level - src/pe/signature - x509.rs (source / functions) Coverage Total Hit
Test: lief.lcov Lines: 75.9 % 87 66
Test Date: 2024-11-30:00:00:00 Functions: 77.3 % 22 17

            Line data    Source code
       1              : use std::marker::PhantomData;
       2              : 
       3              : use lief_ffi as ffi;
       4              : 
       5              : use crate::common::{into_optional, FromFFI};
       6              : use crate::declare_iterator;
       7              : use crate::pe::Algorithms;
       8              : 
       9              : use super::{RsaInfo, VerificationFlags};
      10              : 
      11              : /// Structure for a x509 certificate
      12              : pub struct X509<'a> {
      13              :     ptr: cxx::UniquePtr<ffi::PE_x509>,
      14              :     _owner: PhantomData<&'a ffi::PE_SignerInfo>,
      15              : }
      16              : 
      17              : impl std::fmt::Debug for X509<'_> {
      18          690 :     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
      19          690 :         f.debug_struct("x509")
      20          690 :             .field("version", &self.version())
      21          690 :             .field("signature_algorithm", &self.signature_algorithm())
      22          690 :             .field("valid_from", &self.valid_from())
      23          690 :             .field("valid_to", &self.valid_to())
      24          690 :             .field("issuer", &self.issuer())
      25          690 :             .field("key_type", &self.key_type())
      26          690 :             .field("subject", &self.subject())
      27          690 :             .field("is_ca", &self.is_ca())
      28          690 :             .finish()
      29          690 :     }
      30              : }
      31              : 
      32              : impl<'a> FromFFI<ffi::PE_x509> for X509<'a> {
      33          690 :     fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_x509>) -> Self {
      34          690 :         X509 {
      35          690 :             ptr,
      36          690 :             _owner: PhantomData,
      37          690 :         }
      38          690 :     }
      39              : }
      40              : 
      41              : #[allow(non_camel_case_types)]
      42          690 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
      43              : /// Public key scheme
      44              : pub enum KeyType {
      45              :     /// Unknown scheme
      46              :     NONE,
      47              : 
      48              :     /// RSA Scheme
      49              :     RSA,
      50              : 
      51              :     /// Elliptic-curve scheme
      52              :     ECKEY,
      53              : 
      54              :     /// Elliptic-curve Diffie-Hellman
      55              :     ECKEY_DH,
      56              : 
      57              :     /// Elliptic-curve Digital Signature Algorithm
      58              :     ECDSA,
      59              : 
      60              :     /// RSA scheme with an alternative implementation for signing and decrypting
      61              :     RSA_ALT,
      62              : 
      63              :     /// RSA Probabilistic signature scheme
      64              :     RSASSA_PSS,
      65              :     UNKNOWN(u32),
      66              : }
      67              : 
      68              : impl From<u32> for KeyType {
      69          690 :     fn from(value: u32) -> Self {
      70          690 :         match value {
      71            0 :             0x00000000 => KeyType::NONE,
      72          690 :             0x00000001 => KeyType::RSA,
      73            0 :             0x00000002 => KeyType::ECKEY,
      74            0 :             0x00000003 => KeyType::ECKEY_DH,
      75            0 :             0x00000004 => KeyType::ECDSA,
      76            0 :             0x00000005 => KeyType::RSA_ALT,
      77            0 :             0x00000006 => KeyType::RSASSA_PSS,
      78            0 :             _ => KeyType::UNKNOWN(value),
      79              :         }
      80          690 :     }
      81              : }
      82              : 
      83              : impl X509<'_> {
      84              :     /// X.509 version. (1=v1, 2=v2, 3=v3)
      85          690 :     pub fn version(&self) -> u32 {
      86          690 :         self.ptr.version()
      87          690 :     }
      88              : 
      89              :     /// Unique id for certificate issued by a specific CA.
      90          560 :     pub fn serial_number(&self) -> Vec<u8> {
      91          560 :         Vec::from(self.ptr.serial_number().as_slice())
      92          560 :     }
      93              : 
      94              :     /// Signature algorithm (OID)
      95          690 :     pub fn signature_algorithm(&self) -> String {
      96          690 :         self.ptr.signature_algorithm().to_string()
      97          690 :     }
      98              : 
      99              :     /// Start time of certificate validity
     100          690 :     pub fn valid_from(&self) -> Vec<u64> {
     101          690 :         Vec::from(self.ptr.valid_from().as_slice())
     102          690 :     }
     103              : 
     104              :     /// End time of certificate validity
     105          690 :     pub fn valid_to(&self) -> Vec<u64> {
     106          690 :         Vec::from(self.ptr.valid_to().as_slice())
     107          690 :     }
     108              : 
     109              :     /// Issuer information
     110          690 :     pub fn issuer(&self) -> String {
     111          690 :         self.ptr.issuer().to_string()
     112          690 :     }
     113              : 
     114              :     /// Subject information
     115          690 :     pub fn subject(&self) -> String {
     116          690 :         self.ptr.subject().to_string()
     117          690 :     }
     118              : 
     119              :     /// The raw x509 bytes (DER encoded)
     120          560 :     pub fn raw(&self) -> Vec<u8> {
     121          560 :         Vec::from(self.ptr.raw().as_slice())
     122          560 :     }
     123              : 
     124              :     /// Return the underlying public-key scheme
     125          690 :     pub fn key_type(&self) -> KeyType {
     126          690 :         KeyType::from(self.ptr.key_type())
     127          690 :     }
     128          690 :     pub fn is_ca(&self) -> bool {
     129          690 :         self.ptr.is_ca()
     130          690 :     }
     131              : 
     132              :     /// The signature of the certificate
     133          560 :     pub fn signature(&self) -> Vec<u8> {
     134          560 :         Vec::from(self.ptr.signature().as_slice())
     135          560 :     }
     136              : 
     137              :     /// **If** the underlying public-key scheme is RSA, return the RSA information.
     138          560 :     pub fn rsa_info(&self) -> Option<RsaInfo> {
     139          560 :         into_optional(self.ptr.rsa_info())
     140          560 :     }
     141              : 
     142              :     /// Try to decrypt the given signature and check if it matches the given hash according to
     143              :     /// the hash algorithm provided
     144            0 :     pub fn check_signature(&self, hash: &[u8], signature: &[u8], digest: Algorithms) -> bool {
     145            0 :         unsafe {
     146            0 :             self.ptr.check_signature(
     147            0 :                 hash.as_ptr(),
     148            0 :                 hash.len(),
     149            0 :                 signature.as_ptr(),
     150            0 :                 signature.len(),
     151            0 :                 digest.into(),
     152            0 :             )
     153            0 :         }
     154            0 :     }
     155              : 
     156              :     /// Verify that this certificate has been used **to trust** the given certificate
     157            0 :     pub fn verify(&self, ca: &X509) -> VerificationFlags {
     158            0 :         VerificationFlags::from(self.ptr.verify(ca.ptr.as_ref().unwrap()))
     159            0 :     }
     160              : }
     161              : 
     162          460 : declare_iterator!(
     163          460 :     Certificates,
     164          460 :     X509<'a>,
     165          460 :     ffi::PE_x509,
     166          460 :     ffi::PE_Signature,
     167          460 :     ffi::PE_Signature_it_certificates
     168          460 : );
        

Generated by: LCOV version 2.1-1