2 // https://learn.microsoft.com/en-us/windows-hardware/drivers/install/authenticode
3 // https://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/Authenticode_PE.docx
5 // Authenticode works by omiting sections of the PE binary from the digest
8 // - data directory entry for certtable
16 /// [`authenticode_ranges`] returns the various ranges of the binary that are relevant for
18 pub fn authenticode_ranges(&self) -> ExcludedSectionsIter<'_> {
19 ExcludedSectionsIter {
21 state: IterState::default(),
26 /// [`ExcludedSections`] holds the various ranges of the binary that are expected to be
27 /// excluded from the authenticode computation.
28 #[derive(Debug, Clone, Default)]
29 pub(super) struct ExcludedSections {
30 checksum: Range<usize>,
31 datadir_entry_certtable: Range<usize>,
32 certtable: Option<Range<usize>>,
35 impl ExcludedSections {
37 checksum: Range<usize>,
38 datadir_entry_certtable: Range<usize>,
39 certtable: Option<Range<usize>>,
43 datadir_entry_certtable,
49 pub struct ExcludedSectionsIter<'s> {
54 #[derive(Debug, PartialEq)]
63 impl Default for IterState {
64 fn default() -> Self {
69 impl<'s> Iterator for ExcludedSectionsIter<'s> {
72 fn next(&mut self) -> Option<Self::Item> {
73 let bytes = &self.pe.bytes;
75 if let Some(sections) = self.pe.authenticode_excluded_sections.as_ref() {
78 IterState::Initial => {
79 self.state = IterState::DatadirEntry(sections.checksum.end);
80 return Some(&bytes[..sections.checksum.start]);
82 IterState::DatadirEntry(start) => {
83 self.state = IterState::CertTable(sections.datadir_entry_certtable.end);
84 return Some(&bytes[start..sections.datadir_entry_certtable.start]);
86 IterState::CertTable(start) => {
87 if let Some(certtable) = sections.certtable.as_ref() {
88 self.state = IterState::Final(certtable.end);
89 return Some(&bytes[start..certtable.start]);
91 self.state = IterState::Final(start)
94 IterState::Final(start) => {
95 self.state = IterState::Done;
96 return Some(&bytes[start..]);
98 IterState::Done => return None,
104 IterState::Initial => {
105 self.state = IterState::Done;
108 IterState::Done => return None,
110 self.state = IterState::Done;