Line data Source code
1 : use std::marker::PhantomData;
2 :
3 : use super::attributes::Attribute;
4 : use super::X509;
5 : use crate::pe::Algorithms;
6 : use crate::to_slice;
7 : use crate::common::{FromFFI, into_optional};
8 : use crate::declare_iterator;
9 : use lief_ffi as ffi;
10 :
11 : /// Concrete type of a signature attribute
12 : #[allow(non_camel_case_types)]
13 0 : #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
14 : pub enum AttributeType {
15 : CONTENT_TYPE,
16 : GENERIC_TYPE,
17 : SIGNING_CERTIFICATE_V2,
18 : SPC_SP_OPUS_INFO,
19 : SPC_RELAXED_PE_MARKER_CHECK,
20 : MS_COUNTER_SIGN,
21 : MS_SPC_NESTED_SIGN,
22 : MS_SPC_STATEMENT_TYPE,
23 : MS_PLATFORM_MANIFEST_BINARY_ID,
24 : PKCS9_AT_SEQUENCE_NUMBER,
25 : PKCS9_COUNTER_SIGNATURE,
26 : PKCS9_MESSAGE_DIGEST,
27 : PKCS9_SIGNING_TIME,
28 : UNKNOWN(u32),
29 : }
30 :
31 : impl From<u32> for AttributeType {
32 0 : fn from(value: u32) -> Self {
33 0 : match value {
34 0 : 0x00000001 => AttributeType::CONTENT_TYPE,
35 0 : 0x00000002 => AttributeType::GENERIC_TYPE,
36 0 : 0x00000003 => AttributeType::SIGNING_CERTIFICATE_V2,
37 0 : 0x00000004 => AttributeType::SPC_SP_OPUS_INFO,
38 0 : 0x00000005 => AttributeType::SPC_RELAXED_PE_MARKER_CHECK,
39 0 : 0x00000006 => AttributeType::MS_COUNTER_SIGN,
40 0 : 0x00000007 => AttributeType::MS_SPC_NESTED_SIGN,
41 0 : 0x00000008 => AttributeType::MS_SPC_STATEMENT_TYPE,
42 0 : 0x00000009 => AttributeType::MS_PLATFORM_MANIFEST_BINARY_ID,
43 0 : 0x0000000a => AttributeType::PKCS9_AT_SEQUENCE_NUMBER,
44 0 : 0x0000000b => AttributeType::PKCS9_COUNTER_SIGNATURE,
45 0 : 0x0000000c => AttributeType::PKCS9_MESSAGE_DIGEST,
46 0 : 0x0000000d => AttributeType::PKCS9_SIGNING_TIME,
47 0 : _ => AttributeType::UNKNOWN(value),
48 : }
49 0 : }
50 : }
51 :
52 : impl From<AttributeType> for u32 {
53 0 : fn from(value: AttributeType) -> u32 {
54 0 : match value {
55 0 : AttributeType::CONTENT_TYPE => 0x00000001,
56 0 : AttributeType::GENERIC_TYPE => 0x00000002,
57 0 : AttributeType::SIGNING_CERTIFICATE_V2 => 0x00000003,
58 0 : AttributeType::SPC_SP_OPUS_INFO => 0x00000004,
59 0 : AttributeType::SPC_RELAXED_PE_MARKER_CHECK => 0x00000005,
60 0 : AttributeType::MS_COUNTER_SIGN => 0x00000006,
61 0 : AttributeType::MS_SPC_NESTED_SIGN => 0x00000007,
62 0 : AttributeType::MS_SPC_STATEMENT_TYPE => 0x00000008,
63 0 : AttributeType::MS_PLATFORM_MANIFEST_BINARY_ID => 0x00000009,
64 0 : AttributeType::PKCS9_AT_SEQUENCE_NUMBER => 0x0000000a,
65 0 : AttributeType::PKCS9_COUNTER_SIGNATURE => 0x0000000b,
66 0 : AttributeType::PKCS9_MESSAGE_DIGEST => 0x0000000c,
67 0 : AttributeType::PKCS9_SIGNING_TIME => 0x0000000d,
68 0 : AttributeType::UNKNOWN(v) => v,
69 : }
70 0 : }
71 : }
72 :
73 : /// SignerInfo as described in the [RFC 2315](https://tools.ietf.org/html/rfc2315#section-9.2)
74 : pub struct SignerInfo<'a> {
75 : ptr: cxx::UniquePtr<ffi::PE_SignerInfo>,
76 : _owner: PhantomData<&'a ()>, // Can be own by Signature or PKCS9CounterSignature
77 : }
78 :
79 : impl std::fmt::Debug for SignerInfo<'_> {
80 300 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
81 300 : f.debug_struct("SignerInfo")
82 300 : .field("version", &self.version())
83 300 : .field("issuer", &self.issuer())
84 300 : .field("digest_algorithm", &self.digest_algorithm())
85 300 : .field("encryption_algorithm", &self.encryption_algorithm())
86 300 : .finish()
87 300 : }
88 : }
89 :
90 : impl<'a> FromFFI<ffi::PE_SignerInfo> for SignerInfo<'a> {
91 360 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_SignerInfo>) -> Self {
92 360 : SignerInfo {
93 360 : ptr,
94 360 : _owner: PhantomData,
95 360 : }
96 360 : }
97 : }
98 :
99 : impl<'a> SignerInfo<'a> {
100 : /// Should be 1
101 300 : pub fn version(&self) -> u32 {
102 300 : self.ptr.version()
103 300 : }
104 :
105 : /// Return the [`X509::issuer`] used by this signer
106 300 : pub fn issuer(&self) -> String {
107 300 : self.ptr.issuer().to_string()
108 300 : }
109 :
110 : /// Algorithm used to hash the file.
111 300 : pub fn digest_algorithm(&self) -> Algorithms {
112 300 : Algorithms::from(self.ptr.digest_algorithm())
113 300 : }
114 :
115 : /// Return the (public-key) algorithm used to encrypt the signature
116 300 : pub fn encryption_algorithm(&self) -> Algorithms {
117 300 : Algorithms::from(self.ptr.encryption_algorithm())
118 300 : }
119 :
120 : /// Return the serial number associated with the x509 certificate
121 : /// used by this signer.
122 300 : pub fn serial_number(&self) -> &[u8] {
123 300 : to_slice!(self.ptr.serial_number());
124 300 : }
125 :
126 : /// Return the signature created by the signing certificate's private key
127 300 : pub fn encrypted_digest(&self) -> Vec<u8> {
128 300 : Vec::from(self.ptr.encrypted_digest().as_slice())
129 300 : }
130 :
131 : /// [`X509`] certificate used by this signer.
132 300 : pub fn cert(&self) -> Option<X509<'_>> {
133 300 : into_optional(self.ptr.cert())
134 300 : }
135 :
136 : /// Iterator over the **authenticated** [`Attribute`]
137 360 : pub fn authenticated_attributes(&self) -> AuthenticatedAttributes<'_> {
138 360 : AuthenticatedAttributes::new(self.ptr.authenticated_attributes())
139 360 : }
140 :
141 : /// Iterator over the **unauthenticated** [`Attribute`]
142 360 : pub fn unauthenticated_attributes(&self) -> UnAuthenticatedAttributes<'_> {
143 360 : UnAuthenticatedAttributes::new(self.ptr.unauthenticated_attributes())
144 360 : }
145 :
146 : /// Raw blob that is signed by the signer certificate
147 60 : pub fn raw_auth_data(&self) -> &[u8] {
148 60 : to_slice!(self.ptr.raw_auth_data());
149 60 : }
150 :
151 : /// Return the first authenticated or unauthenticated attribute matching the given type
152 0 : pub fn get_attribute(&self, attr_type: AttributeType) -> Option<Attribute<'_>> {
153 0 : into_optional(self.ptr.get_attribute(attr_type.into()))
154 0 : }
155 :
156 : /// Return the first authenticated attribute matching the given type
157 0 : pub fn get_auth_attribute(&self, attr_type: AttributeType) -> Option<Attribute<'_>> {
158 0 : into_optional(self.ptr.get_auth_attribute(attr_type.into()))
159 0 : }
160 :
161 : /// Return the first unauthenticated attribute matching the given type
162 0 : pub fn get_unauth_attribute(&self, attr_type: AttributeType) -> Option<Attribute<'_>> {
163 0 : into_optional(self.ptr.get_unauth_attribute(attr_type.into()))
164 0 : }
165 : }
166 :
167 192 : declare_iterator!(
168 192 : Signers,
169 192 : SignerInfo<'a>,
170 192 : ffi::PE_SignerInfo,
171 192 : ffi::PE_Signature,
172 192 : ffi::PE_Signature_it_signers
173 192 : );
174 1332 : declare_iterator!(
175 1332 : AuthenticatedAttributes,
176 1332 : Attribute<'a>,
177 1332 : ffi::PE_Attribute,
178 1332 : ffi::PE_SignerInfo,
179 1332 : ffi::PE_SignerInfo_it_authenticated_attributes
180 1332 : );
181 204 : declare_iterator!(
182 204 : UnAuthenticatedAttributes,
183 204 : Attribute<'a>,
184 204 : ffi::PE_Attribute,
185 204 : ffi::PE_SignerInfo,
186 204 : ffi::PE_SignerInfo_it_unauthenticated_attributes
187 204 : );
|