1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
use crate::{Error, Result};
use crate::security::Security;
use crate::util::AlignTo;

use super::image::*;
use super::{Align, Pe};

pub(crate) fn try_from<'a, P: Pe<'a>>(pe: P) -> Result<Security<'a>> {
	// The security info is part of the mapped image
	if pe.align() != Align::File {
		return Err(Error::Unmapped);
	}
	// Manual alignment and size check
	let datadir = pe.data_directory().get(IMAGE_DIRECTORY_ENTRY_SECURITY).ok_or(Error::Bounds)?;
	if datadir.VirtualAddress == 0 {
		return Err(Error::Null);
	}
	if !datadir.VirtualAddress.aligned_to(8) || !datadir.Size.aligned_to(8) {
		return Err(Error::Misaligned);
	}
	if datadir.Size == 0 {
		return Err(Error::Bounds);
	}
	// Interpret the bytes
	let start = datadir.VirtualAddress as usize;
	let end = (datadir.VirtualAddress + datadir.Size) as usize;
	let image = pe.image().get(start..end).ok_or(Error::Bounds)?;
	Ok(unsafe { Security::new(image) })
}

#[cfg(test)]
pub(crate) fn test<'a, P: Pe<'a>>(pe: P) -> Result<()> {
	let security = pe.security()?;
	let _ = format!("{:?}", security);
	let _certificate_type = security.certificate_type();
	let _certificate_data = security.certificate_data();
	Ok(())
}