Line data Source code
1 : use std::marker::PhantomData;
2 :
3 : use lief_ffi as ffi;
4 :
5 : use crate::common::FromFFI;
6 : use crate::to_slice;
7 : use crate::pe::Algorithms;
8 : use crate::pe::signature::ContentInfo;
9 : use crate::declare_iterator;
10 : use crate::pe::signature::X509;
11 :
12 : use super::{Signature, SignerInfo};
13 :
14 0 : #[derive(Debug)]
15 : /// This enum exposes the different attributes that can be wrapped in
16 : /// a [`crate::pe::signature::SignerInfo`]
17 : pub enum Attribute<'a> {
18 : /// Attribute for the OID: `1.2.840.113549.1.9.3`
19 : ContentType(ContentType<'a>),
20 : /// Attribute for the OID: `1.3.6.1.4.1.311.2.4.1`
21 : MsSpcNestedSignature(MsSpcNestedSignature<'a>),
22 : /// Attribute for the OID: `1.3.6.1.4.1.311.2.1.11`
23 : MsSpcStatementType(MsSpcStatementType<'a>),
24 : /// Attribute for the OID: `1.2.840.113549.1.9.25.4`
25 : PKCS9AtSequenceNumber(PKCS9AtSequenceNumber<'a>),
26 : /// Attribute for the OID: `1.2.840.113549.1.9.6`
27 : PKCS9CounterSignature(PKCS9CounterSignature<'a>),
28 : /// Attribute for the OID: `1.2.840.113549.1.9.4`
29 : PKCS9MessageDigest(PKCS9MessageDigest<'a>),
30 : /// Attribute for the OID: `1.2.840.113549.1.9.5`
31 : PKCS9SigningTime(PKCS9SigningTime<'a>),
32 : /// Attribute for the OID: `1.3.6.1.4.1.311.2.1.12`
33 : SpcSpOpusInfo(SpcSpOpusInfo<'a>),
34 : /// Attribute for the OID: `1.3.6.1.4.1.311.10.3.28`
35 : MsManifestBinaryID(MsManifestBinaryID<'a>),
36 : /// Attribute for the OID: `1.3.6.1.4.1.311.3.3.1`
37 : MsCounterSign(MsCounterSign<'a>),
38 : /// Attribute for the OID: `1.2.840.113549.1.9.16.2.47`
39 : SigningCertificateV2(SigningCertificateV2<'a>),
40 : /// Attribute for the OID: `1.3.6.1.4.1.311.2.6.1`
41 : SpcRelaxedPeMarkerCheck(SpcRelaxedPeMarkerCheck<'a>),
42 : /// Attribute for an OID not supported by LIEF
43 : GenericType(GenericType<'a>),
44 : }
45 :
46 : impl<'a> FromFFI<ffi::PE_Attribute> for Attribute<'a> {
47 1280 : fn from_ffi(ffi_entry: cxx::UniquePtr<ffi::PE_Attribute>) -> Self {
48 1280 : unsafe {
49 1280 : let cmd_ref = ffi_entry.as_ref().unwrap();
50 1280 :
51 1280 : if ffi::PE_ContentType::classof(cmd_ref) {
52 300 : let raw = {
53 300 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
54 300 : type To = cxx::UniquePtr<ffi::PE_ContentType>;
55 300 : std::mem::transmute::<From, To>(ffi_entry)
56 300 : };
57 300 : Attribute::ContentType(ContentType::from_ffi(raw))
58 980 : } else if ffi::PE_MsSpcNestedSignature::classof(cmd_ref) {
59 30 : let raw = {
60 30 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
61 30 : type To = cxx::UniquePtr<ffi::PE_MsSpcNestedSignature>;
62 30 : std::mem::transmute::<From, To>(ffi_entry)
63 30 : };
64 30 : Attribute::MsSpcNestedSignature(MsSpcNestedSignature::from_ffi(raw))
65 950 : } else if ffi::PE_MsSpcStatementType::classof(cmd_ref) {
66 140 : let raw = {
67 140 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
68 140 : type To = cxx::UniquePtr<ffi::PE_MsSpcStatementType>;
69 140 : std::mem::transmute::<From, To>(ffi_entry)
70 140 : };
71 140 : Attribute::MsSpcStatementType(MsSpcStatementType::from_ffi(raw))
72 810 : } else if ffi::PE_PKCS9AtSequenceNumber::classof(cmd_ref) {
73 20 : let raw = {
74 20 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
75 20 : type To = cxx::UniquePtr<ffi::PE_PKCS9AtSequenceNumber>;
76 20 : std::mem::transmute::<From, To>(ffi_entry)
77 20 : };
78 20 : Attribute::PKCS9AtSequenceNumber(PKCS9AtSequenceNumber::from_ffi(raw))
79 790 : } else if ffi::PE_PKCS9CounterSignature::classof(cmd_ref) {
80 50 : let raw = {
81 50 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
82 50 : type To = cxx::UniquePtr<ffi::PE_PKCS9CounterSignature>;
83 50 : std::mem::transmute::<From, To>(ffi_entry)
84 50 : };
85 50 : Attribute::PKCS9CounterSignature(PKCS9CounterSignature::from_ffi(raw))
86 740 : } else if ffi::PE_PKCS9MessageDigest::classof(cmd_ref) {
87 300 : let raw = {
88 300 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
89 300 : type To = cxx::UniquePtr<ffi::PE_PKCS9MessageDigest>;
90 300 : std::mem::transmute::<From, To>(ffi_entry)
91 300 : };
92 300 : Attribute::PKCS9MessageDigest(PKCS9MessageDigest::from_ffi(raw))
93 440 : } else if ffi::PE_PKCS9SigningTime::classof(cmd_ref) {
94 110 : let raw = {
95 110 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
96 110 : type To = cxx::UniquePtr<ffi::PE_PKCS9SigningTime>;
97 110 : std::mem::transmute::<From, To>(ffi_entry)
98 110 : };
99 110 : Attribute::PKCS9SigningTime(PKCS9SigningTime::from_ffi(raw))
100 330 : } else if ffi::PE_SpcSpOpusInfo::classof(cmd_ref) {
101 120 : let raw = {
102 120 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
103 120 : type To = cxx::UniquePtr<ffi::PE_SpcSpOpusInfo>;
104 120 : std::mem::transmute::<From, To>(ffi_entry)
105 120 : };
106 120 : Attribute::SpcSpOpusInfo(SpcSpOpusInfo::from_ffi(raw))
107 210 : } else if ffi::PE_MsManifestBinaryID::classof(cmd_ref) {
108 10 : let raw = {
109 10 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
110 10 : type To = cxx::UniquePtr<ffi::PE_MsManifestBinaryID>;
111 10 : std::mem::transmute::<From, To>(ffi_entry)
112 10 : };
113 10 : Attribute::MsManifestBinaryID(MsManifestBinaryID::from_ffi(raw))
114 200 : } else if ffi::PE_MsCounterSign::classof(cmd_ref) {
115 90 : let raw = {
116 90 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
117 90 : type To = cxx::UniquePtr<ffi::PE_MsCounterSign>;
118 90 : std::mem::transmute::<From, To>(ffi_entry)
119 90 : };
120 90 : Attribute::MsCounterSign(MsCounterSign::from_ffi(raw))
121 110 : } else if ffi::PE_SpcRelaxedPeMarkerCheck::classof(cmd_ref) {
122 20 : let raw = {
123 20 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
124 20 : type To = cxx::UniquePtr<ffi::PE_SpcRelaxedPeMarkerCheck>;
125 20 : std::mem::transmute::<From, To>(ffi_entry)
126 20 : };
127 20 : Attribute::SpcRelaxedPeMarkerCheck(SpcRelaxedPeMarkerCheck::from_ffi(raw))
128 90 : } else if ffi::PE_SigningCertificateV2::classof(cmd_ref) {
129 60 : let raw = {
130 60 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
131 60 : type To = cxx::UniquePtr<ffi::PE_SigningCertificateV2>;
132 60 : std::mem::transmute::<From, To>(ffi_entry)
133 60 : };
134 60 : Attribute::SigningCertificateV2(SigningCertificateV2::from_ffi(raw))
135 : } else {
136 30 : assert!(
137 30 : ffi::PE_GenericType::classof(cmd_ref),
138 0 : "Must be a GenericType node"
139 : );
140 30 : let raw = {
141 30 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
142 30 : type To = cxx::UniquePtr<ffi::PE_GenericType>;
143 30 : std::mem::transmute::<From, To>(ffi_entry)
144 30 : };
145 30 : Attribute::GenericType(GenericType::from_ffi(raw))
146 : }
147 : }
148 1280 : }
149 : }
150 : /// Interface over the structure described by the OID ``1.2.840.113549.1.9.3`` (PKCS #9)
151 : ///
152 : /// The internal structure is described in the RFC #2985
153 : ///
154 : /// ```text
155 : /// ContentType ::= OBJECT IDENTIFIER
156 : /// ```
157 : pub struct ContentType<'a> {
158 : ptr: cxx::UniquePtr<ffi::PE_ContentType>,
159 : _owner: PhantomData<&'a ffi::PE_SignerInfo>,
160 : }
161 :
162 : impl std::fmt::Debug for ContentType<'_> {
163 300 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
164 300 : f.debug_struct("ContentType")
165 300 : .field("oid", &self.oid())
166 300 : .finish()
167 300 : }
168 : }
169 :
170 : impl<'a> FromFFI<ffi::PE_ContentType> for ContentType<'a> {
171 300 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_ContentType>) -> Self {
172 300 : Self {
173 300 : ptr,
174 300 : _owner: PhantomData,
175 300 : }
176 300 : }
177 : }
178 :
179 : impl ContentType<'_> {
180 : /// OID as described in RFC #2985
181 300 : pub fn oid(&self) -> String {
182 300 : self.ptr.oid().to_string()
183 300 : }
184 : }
185 :
186 : /// Interface over an attribute for which the internal structure is not supported by LIEF
187 : pub struct GenericType<'a> {
188 : ptr: cxx::UniquePtr<ffi::PE_GenericType>,
189 : _owner: PhantomData<&'a ffi::PE_SignerInfo>,
190 : }
191 :
192 : impl std::fmt::Debug for GenericType<'_> {
193 30 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
194 30 : f.debug_struct("GenericType")
195 30 : .field("oid", &self.oid())
196 30 : .finish()
197 30 : }
198 : }
199 :
200 : impl<'a> FromFFI<ffi::PE_GenericType> for GenericType<'a> {
201 30 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_GenericType>) -> Self {
202 30 : Self {
203 30 : ptr,
204 30 : _owner: PhantomData,
205 30 : }
206 30 : }
207 : }
208 :
209 : impl GenericType<'_> {
210 : /// OID of the original attribute
211 30 : pub fn oid(&self) -> String {
212 30 : self.ptr.oid().to_string()
213 30 : }
214 :
215 : /// Original DER blob of the attribute
216 0 : pub fn raw_content(&self) -> &[u8] {
217 0 : to_slice!(self.ptr.raw_content());
218 0 : }
219 : }
220 :
221 : /// Interface over the structure described by the OID `1.3.6.1.4.1.311.2.4.1`
222 : ///
223 : /// The internal structure is not documented but we can infer the following structure:
224 : ///
225 : /// ```text
226 : /// MsSpcNestedSignature ::= SET OF SignedData
227 : /// ```
228 : ///
229 : /// `SignedData` is the structure described in PKCS #7 RFC
230 : pub struct MsSpcNestedSignature<'a> {
231 : ptr: cxx::UniquePtr<ffi::PE_MsSpcNestedSignature>,
232 : _owner: PhantomData<&'a ffi::PE_SignerInfo>,
233 : }
234 :
235 : impl std::fmt::Debug for MsSpcNestedSignature<'_> {
236 30 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
237 30 : f.debug_struct("MsSpcNestedSignature").finish()
238 30 : }
239 : }
240 :
241 : impl<'a> FromFFI<ffi::PE_MsSpcNestedSignature> for MsSpcNestedSignature<'a> {
242 30 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_MsSpcNestedSignature>) -> Self {
243 30 : Self {
244 30 : ptr,
245 30 : _owner: PhantomData,
246 30 : }
247 30 : }
248 : }
249 :
250 : impl MsSpcNestedSignature<'_> {
251 : /// Underlying Signature object
252 30 : pub fn signature(&self) -> Signature {
253 30 : Signature::from_ffi(self.ptr.sig())
254 30 : }
255 : }
256 :
257 : /// Interface over the structure described by the OID `1.3.6.1.4.1.311.2.1.11`
258 : ///
259 : /// The internal structure is described in the official document:
260 : /// *Windows Authenticode Portable Executable Signature Format*
261 : ///
262 : /// ```text
263 : /// SpcStatementType ::= SEQUENCE of OBJECT IDENTIFIER
264 : /// ```
265 : pub struct MsSpcStatementType<'a> {
266 : ptr: cxx::UniquePtr<ffi::PE_MsSpcStatementType>,
267 : _owner: PhantomData<&'a ffi::PE_SignerInfo>,
268 : }
269 :
270 : impl std::fmt::Debug for MsSpcStatementType<'_> {
271 140 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
272 140 : f.debug_struct("MsSpcStatementType")
273 140 : .field("oid", &self.oid())
274 140 : .finish()
275 140 : }
276 : }
277 :
278 : impl<'a> FromFFI<ffi::PE_MsSpcStatementType> for MsSpcStatementType<'a> {
279 140 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_MsSpcStatementType>) -> Self {
280 140 : Self {
281 140 : ptr,
282 140 : _owner: PhantomData,
283 140 : }
284 140 : }
285 : }
286 :
287 : impl MsSpcStatementType<'_> {
288 : /// According to the documentation:
289 : /// > The SpcStatementType MUST contain one Object Identifier with either
290 : /// > the value `1.3.6.1.4.1.311.2.1.21 (SPC_INDIVIDUAL_SP_KEY_PURPOSE_OBJID)` or
291 : /// > `1.3.6.1.4.1.311.2.1.22 (SPC_COMMERCIAL_SP_KEY_PURPOSE_OBJID)`.
292 140 : pub fn oid(&self) -> String {
293 140 : self.ptr.oid().to_string()
294 140 : }
295 : }
296 :
297 : /// Interface over the structure described by the OID `1.2.840.113549.1.9.25.4` (PKCS #9)
298 : ///
299 : /// The internal structure is described in the
300 : /// RFC #2985: PKCS #9 - Selected Object Classes and Attribute Types Version 2.0
301 : ///
302 : /// ```text
303 : /// sequenceNumber ATTRIBUTE ::= {
304 : /// WITH SYNTAX SequenceNumber
305 : /// EQUALITY MATCHING RULE integerMatch
306 : /// SINGLE VALUE TRUE
307 : /// ID pkcs-9-at-sequenceNumber
308 : /// }
309 : ///
310 : /// SequenceNumber ::= INTEGER (1..MAX)
311 : /// ```
312 : pub struct PKCS9AtSequenceNumber<'a> {
313 : ptr: cxx::UniquePtr<ffi::PE_PKCS9AtSequenceNumber>,
314 : _owner: PhantomData<&'a ffi::PE_SignerInfo>,
315 : }
316 :
317 : impl std::fmt::Debug for PKCS9AtSequenceNumber<'_> {
318 20 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
319 20 : f.debug_struct("PKCS9AtSequenceNumber")
320 20 : .field("number", &self.number())
321 20 : .finish()
322 20 : }
323 : }
324 :
325 : impl PKCS9AtSequenceNumber<'_> {
326 : //! Number as described in the RFC
327 20 : pub fn number(&self) -> u32 {
328 20 : self.ptr.number()
329 20 : }
330 : }
331 :
332 : impl<'a> FromFFI<ffi::PE_PKCS9AtSequenceNumber> for PKCS9AtSequenceNumber<'a> {
333 20 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_PKCS9AtSequenceNumber>) -> Self {
334 20 : Self {
335 20 : ptr,
336 20 : _owner: PhantomData,
337 20 : }
338 20 : }
339 : }
340 :
341 : /// Interface over the structure described by the OID `1.2.840.113549.1.9.6` (PKCS #9)
342 : ///
343 : /// The internal structure is described in the
344 : /// RFC #2985: PKCS #9 - Selected Object Classes and Attribute Types Version 2.0
345 : ///
346 : /// ```text
347 : /// counterSignature ATTRIBUTE ::= {
348 : /// WITH SYNTAX SignerInfo
349 : /// ID pkcs-9-at-counterSignature
350 : /// }
351 : /// ```
352 : pub struct PKCS9CounterSignature<'a> {
353 : ptr: cxx::UniquePtr<ffi::PE_PKCS9CounterSignature>,
354 : _owner: PhantomData<&'a ffi::PE_SignerInfo>,
355 : }
356 :
357 : impl std::fmt::Debug for PKCS9CounterSignature<'_> {
358 50 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
359 50 : f.debug_struct("PKCS9CounterSignature").finish()
360 50 : }
361 : }
362 :
363 : impl<'a> FromFFI<ffi::PE_PKCS9CounterSignature> for PKCS9CounterSignature<'a> {
364 50 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_PKCS9CounterSignature>) -> Self {
365 50 : Self {
366 50 : ptr,
367 50 : _owner: PhantomData,
368 50 : }
369 50 : }
370 : }
371 :
372 : impl PKCS9CounterSignature<'_> {
373 : /// SignerInfo as described in the RFC #2985
374 50 : pub fn signer(&self) -> SignerInfo {
375 50 : SignerInfo::from_ffi(self.ptr.signer())
376 50 : }
377 : }
378 :
379 : /// Interface over the structure described by the OID `1.2.840.113549.1.9.4` (PKCS #9)
380 : ///
381 : /// The internal structure is described in the
382 : /// RFC #2985: PKCS #9 - Selected Object Classes and Attribute Types Version 2.0
383 : ///
384 : /// ```text
385 : /// messageDigest ATTRIBUTE ::= {
386 : /// WITH SYNTAX MessageDigest
387 : /// EQUALITY MATCHING RULE octetStringMatch
388 : /// SINGLE VALUE TRUE
389 : /// ID pkcs-9-at-messageDigest
390 : /// }
391 : ///
392 : /// MessageDigest ::= OCTET STRING
393 : /// ```
394 : pub struct PKCS9MessageDigest<'a> {
395 : ptr: cxx::UniquePtr<ffi::PE_PKCS9MessageDigest>,
396 : _owner: PhantomData<&'a ffi::PE_SignerInfo>,
397 : }
398 :
399 : impl std::fmt::Debug for PKCS9MessageDigest<'_> {
400 300 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
401 300 : f.debug_struct("PKCS9MessageDigest").finish()
402 300 : }
403 : }
404 :
405 : impl PKCS9MessageDigest<'_> {
406 : /// Message digeset as a blob of bytes as described in the RFC
407 300 : pub fn digest(&self) -> &[u8] {
408 300 : to_slice!(self.ptr.digest());
409 300 : }
410 : }
411 :
412 : impl<'a> FromFFI<ffi::PE_PKCS9MessageDigest> for PKCS9MessageDigest<'a> {
413 300 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_PKCS9MessageDigest>) -> Self {
414 300 : Self {
415 300 : ptr,
416 300 : _owner: PhantomData,
417 300 : }
418 300 : }
419 : }
420 :
421 : /// Interface over the structure described by the OID `1.2.840.113549.1.9.5` (PKCS #9)
422 : ///
423 : /// The internal structure is described in the
424 : /// RFC #2985: PKCS #9 - Selected Object Classes and Attribute Types Version 2.0
425 : ///
426 : /// ```text
427 : /// signingTime ATTRIBUTE ::= {
428 : /// WITH SYNTAX SigningTime
429 : /// EQUALITY MATCHING RULE signingTimeMatch
430 : /// SINGLE VALUE TRUE
431 : /// ID pkcs-9-at-signingTime
432 : /// }
433 : ///
434 : /// SigningTime ::= Time -- imported from ISO/IEC 9594-8
435 : /// ```
436 : pub struct PKCS9SigningTime<'a> {
437 : ptr: cxx::UniquePtr<ffi::PE_PKCS9SigningTime>,
438 : _owner: PhantomData<&'a ffi::PE_SignerInfo>,
439 : }
440 :
441 : impl std::fmt::Debug for PKCS9SigningTime<'_> {
442 110 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
443 110 : f.debug_struct("PKCS9SigningTime")
444 110 : .field("time", &self.time())
445 110 : .finish()
446 110 : }
447 : }
448 :
449 : impl<'a> FromFFI<ffi::PE_PKCS9SigningTime> for PKCS9SigningTime<'a> {
450 110 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_PKCS9SigningTime>) -> Self {
451 110 : Self {
452 110 : ptr,
453 110 : _owner: PhantomData,
454 110 : }
455 110 : }
456 : }
457 :
458 : impl PKCS9SigningTime<'_> {
459 : /// Time as a tuple: `(year, month, day, hour, min, sec)`
460 110 : pub fn time(&self) -> (u64, u64, u64, u64, u64, u64) {
461 110 : let vec = Vec::from(self.ptr.time().as_slice());
462 110 : if vec.len() != 6 {
463 0 : return (0, 0, 0, 0, 0, 0);
464 110 : }
465 110 : (vec[0], vec[1], vec[2], vec[3], vec[4], vec[5])
466 110 : }
467 : }
468 :
469 : /// Interface over the structure described by the OID `1.3.6.1.4.1.311.2.1.12`
470 : ///
471 : /// The internal structure is described in the official document:
472 : /// *Windows Authenticode Portable Executable Signature Format*
473 : ///
474 : /// ```text
475 : /// SpcSpOpusInfo ::= SEQUENCE {
476 : /// programName [0] EXPLICIT SpcString OPTIONAL,
477 : /// moreInfo [1] EXPLICIT SpcLink OPTIONAL
478 : /// }
479 : /// ```
480 : pub struct SpcSpOpusInfo<'a> {
481 : ptr: cxx::UniquePtr<ffi::PE_SpcSpOpusInfo>,
482 : _owner: PhantomData<&'a ffi::PE_SignerInfo>,
483 : }
484 :
485 : impl std::fmt::Debug for SpcSpOpusInfo<'_> {
486 120 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
487 120 : f.debug_struct("SpcSpOpusInfo")
488 120 : .field("program_name", &self.program_name())
489 120 : .field("more_info", &self.more_info())
490 120 : .finish()
491 120 : }
492 : }
493 :
494 : impl<'a> FromFFI<ffi::PE_SpcSpOpusInfo> for SpcSpOpusInfo<'a> {
495 120 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_SpcSpOpusInfo>) -> Self {
496 120 : Self {
497 120 : ptr,
498 120 : _owner: PhantomData,
499 120 : }
500 120 : }
501 : }
502 :
503 : impl SpcSpOpusInfo<'_> {
504 : /// Program description provided by the publisher
505 120 : pub fn program_name(&self) -> String {
506 120 : self.ptr.program_name().to_string()
507 120 : }
508 :
509 : /// Other information such as an url
510 120 : pub fn more_info(&self) -> String {
511 120 : self.ptr.more_info().to_string()
512 120 : }
513 : }
514 :
515 : pub struct SpcRelaxedPeMarkerCheck<'a> {
516 : #[allow(dead_code)]
517 : ptr: cxx::UniquePtr<ffi::PE_SpcRelaxedPeMarkerCheck>,
518 : _owner: PhantomData<&'a ffi::PE_SignerInfo>,
519 : }
520 :
521 : impl std::fmt::Debug for SpcRelaxedPeMarkerCheck<'_> {
522 0 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
523 0 : f.debug_struct("SpcRelaxedPeMarkerCheck")
524 0 : .finish()
525 0 : }
526 : }
527 :
528 : impl<'a> FromFFI<ffi::PE_SpcRelaxedPeMarkerCheck> for SpcRelaxedPeMarkerCheck<'a> {
529 20 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_SpcRelaxedPeMarkerCheck>) -> Self {
530 20 : Self {
531 20 : ptr,
532 20 : _owner: PhantomData,
533 20 : }
534 20 : }
535 : }
536 :
537 : impl SpcRelaxedPeMarkerCheck<'_> {
538 :
539 : }
540 :
541 :
542 : /// ```text
543 : /// SigningCertificateV2 ::= SEQUENCE {
544 : /// certs SEQUENCE OF ESSCertIDv2,
545 : /// policies SEQUENCE OF PolicyInformation OPTIONAL
546 : /// }
547 : ///
548 : /// ESSCertIDv2 ::= SEQUENCE {
549 : /// hashAlgorithm AlgorithmIdentifier DEFAULT {algorithm id-sha256},
550 : /// certHash OCTET STRING,
551 : /// issuerSerial IssuerSerial OPTIONAL
552 : /// }
553 : ///
554 : /// IssuerSerial ::= SEQUENCE {
555 : /// issuer GeneralNames,
556 : /// serialNumber CertificateSerialNumber
557 : /// }
558 : ///
559 : /// PolicyInformation ::= SEQUENCE {
560 : /// policyIdentifier OBJECT IDENTIFIER,
561 : /// policyQualifiers SEQUENCE SIZE (1..MAX) OF PolicyQualifierInfo OPTIONAL
562 : /// }
563 : /// ```
564 : pub struct SigningCertificateV2<'a> {
565 : #[allow(dead_code)]
566 : ptr: cxx::UniquePtr<ffi::PE_SigningCertificateV2>,
567 : _owner: PhantomData<&'a ffi::PE_SignerInfo>,
568 : }
569 :
570 : impl std::fmt::Debug for SigningCertificateV2<'_> {
571 0 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
572 0 : f.debug_struct("SigningCertificateV2")
573 0 : .finish()
574 0 : }
575 : }
576 :
577 : impl<'a> FromFFI<ffi::PE_SigningCertificateV2> for SigningCertificateV2<'a> {
578 60 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_SigningCertificateV2>) -> Self {
579 60 : Self {
580 60 : ptr,
581 60 : _owner: PhantomData,
582 60 : }
583 60 : }
584 : }
585 :
586 : impl SigningCertificateV2<'_> {
587 : // TODO(romain): Add API
588 : }
589 :
590 : /// This structure exposes the MS Counter Signature attribute
591 : pub struct MsCounterSign<'a> {
592 : ptr: cxx::UniquePtr<ffi::PE_MsCounterSign>,
593 : _owner: PhantomData<&'a ffi::PE_SignerInfo>,
594 : }
595 :
596 : impl std::fmt::Debug for MsCounterSign<'_> {
597 0 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
598 0 : f.debug_struct("MsCounterSign")
599 0 : .finish()
600 0 : }
601 : }
602 :
603 : impl<'a> FromFFI<ffi::PE_MsCounterSign> for MsCounterSign<'a> {
604 90 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_MsCounterSign>) -> Self {
605 90 : Self {
606 90 : ptr,
607 90 : _owner: PhantomData,
608 90 : }
609 90 : }
610 : }
611 :
612 : impl<'a> MsCounterSign<'a> {
613 0 : pub fn version(&self) -> u32 {
614 0 : self.ptr.version()
615 0 : }
616 :
617 0 : pub fn digest_algorithm(&self) -> Algorithms {
618 0 : Algorithms::from(self.ptr.digest_algorithm())
619 0 : }
620 :
621 : /// ContentInfo as described in the RFC2315 <https://tools.ietf.org/html/rfc2315#section-7>
622 180 : pub fn content_info(&'a self) -> ContentInfo<'a> {
623 180 : ContentInfo::from_ffi(self.ptr.content_info())
624 180 : }
625 :
626 : /// Return list of [`crate::pe::signature::X509`] certificates associated with this signature
627 90 : pub fn certificates(&'a self) -> MsCounterCertificates<'a> {
628 90 : MsCounterCertificates::new(self.ptr.certificates())
629 90 : }
630 :
631 : /// Iterator over the signer [`SignerInfo`] defined in the PKCS #7 signature
632 90 : pub fn signers(&'a self) -> MsCounterSigners<'a> {
633 90 : MsCounterSigners::new(self.ptr.signers())
634 90 : }
635 : }
636 :
637 160 : declare_iterator!(
638 160 : MsCounterCertificates,
639 160 : X509<'a>,
640 160 : ffi::PE_x509,
641 160 : ffi::PE_MsCounterSign,
642 160 : ffi::PE_MsCounterSign_it_certificates
643 160 : );
644 :
645 90 : declare_iterator!(
646 90 : MsCounterSigners,
647 90 : SignerInfo<'a>,
648 90 : ffi::PE_SignerInfo,
649 90 : ffi::PE_MsCounterSign,
650 90 : ffi::PE_MsCounterSign_it_signers
651 90 : );
652 :
653 : /// Interface over the structure described by the OID `1.3.6.1.4.1.311.10.3.28` (szOID_PLATFORM_MANIFEST_BINARY_ID)
654 : ///
655 : /// The internal structure is not documented but we can infer the following structure:
656 : ///
657 : /// ```text
658 : /// szOID_PLATFORM_MANIFEST_BINARY_ID ::= SET OF BinaryID
659 : /// ```
660 : ///
661 : /// `BinaryID` being an alias of UTF8STRING
662 : pub struct MsManifestBinaryID<'a> {
663 : ptr: cxx::UniquePtr<ffi::PE_MsManifestBinaryID>,
664 : _owner: PhantomData<&'a ffi::PE_SignerInfo>,
665 : }
666 :
667 : impl std::fmt::Debug for MsManifestBinaryID<'_> {
668 0 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
669 0 : f.debug_struct("MsManifestBinaryID")
670 0 : .field("manifest_id", &self.manifest_id())
671 0 : .finish()
672 0 : }
673 : }
674 :
675 : impl<'a> FromFFI<ffi::PE_MsManifestBinaryID> for MsManifestBinaryID<'a> {
676 10 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_MsManifestBinaryID>) -> Self {
677 10 : Self {
678 10 : ptr,
679 10 : _owner: PhantomData,
680 10 : }
681 10 : }
682 : }
683 :
684 : impl MsManifestBinaryID<'_> {
685 10 : pub fn manifest_id(&self) -> String {
686 10 : self.ptr.manifest_id().to_string()
687 10 : }
688 : }
|