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 1020 : fn from_ffi(ffi_entry: cxx::UniquePtr<ffi::PE_Attribute>) -> Self {
48 1020 : unsafe {
49 1020 : let cmd_ref = ffi_entry.as_ref().unwrap();
50 1020 :
51 1020 : if ffi::PE_ContentType::classof(cmd_ref) {
52 240 : let raw = {
53 240 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
54 240 : type To = cxx::UniquePtr<ffi::PE_ContentType>;
55 240 : std::mem::transmute::<From, To>(ffi_entry)
56 240 : };
57 240 : Attribute::ContentType(ContentType::from_ffi(raw))
58 780 : } 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 750 : } else if ffi::PE_MsSpcStatementType::classof(cmd_ref) {
66 110 : let raw = {
67 110 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
68 110 : type To = cxx::UniquePtr<ffi::PE_MsSpcStatementType>;
69 110 : std::mem::transmute::<From, To>(ffi_entry)
70 110 : };
71 110 : Attribute::MsSpcStatementType(MsSpcStatementType::from_ffi(raw))
72 640 : } 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 620 : } 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 570 : } else if ffi::PE_PKCS9MessageDigest::classof(cmd_ref) {
87 240 : let raw = {
88 240 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
89 240 : type To = cxx::UniquePtr<ffi::PE_PKCS9MessageDigest>;
90 240 : std::mem::transmute::<From, To>(ffi_entry)
91 240 : };
92 240 : Attribute::PKCS9MessageDigest(PKCS9MessageDigest::from_ffi(raw))
93 330 : } 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 220 : } else if ffi::PE_SpcSpOpusInfo::classof(cmd_ref) {
101 90 : let raw = {
102 90 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
103 90 : type To = cxx::UniquePtr<ffi::PE_SpcSpOpusInfo>;
104 90 : std::mem::transmute::<From, To>(ffi_entry)
105 90 : };
106 90 : Attribute::SpcSpOpusInfo(SpcSpOpusInfo::from_ffi(raw))
107 130 : } 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 120 : } else if ffi::PE_MsCounterSign::classof(cmd_ref) {
115 60 : let raw = {
116 60 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
117 60 : type To = cxx::UniquePtr<ffi::PE_MsCounterSign>;
118 60 : std::mem::transmute::<From, To>(ffi_entry)
119 60 : };
120 60 : Attribute::MsCounterSign(MsCounterSign::from_ffi(raw))
121 60 : } else if ffi::PE_SpcRelaxedPeMarkerCheck::classof(cmd_ref) {
122 0 : let raw = {
123 0 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
124 0 : type To = cxx::UniquePtr<ffi::PE_SpcRelaxedPeMarkerCheck>;
125 0 : std::mem::transmute::<From, To>(ffi_entry)
126 0 : };
127 0 : Attribute::SpcRelaxedPeMarkerCheck(SpcRelaxedPeMarkerCheck::from_ffi(raw))
128 60 : } else if ffi::PE_SigningCertificateV2::classof(cmd_ref) {
129 30 : let raw = {
130 30 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
131 30 : type To = cxx::UniquePtr<ffi::PE_SigningCertificateV2>;
132 30 : std::mem::transmute::<From, To>(ffi_entry)
133 30 : };
134 30 : 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 1020 : }
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 240 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
164 240 : f.debug_struct("ContentType")
165 240 : .field("oid", &self.oid())
166 240 : .finish()
167 240 : }
168 : }
169 :
170 : impl<'a> FromFFI<ffi::PE_ContentType> for ContentType<'a> {
171 240 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_ContentType>) -> Self {
172 240 : Self {
173 240 : ptr,
174 240 : _owner: PhantomData,
175 240 : }
176 240 : }
177 : }
178 :
179 : impl ContentType<'_> {
180 : /// OID as described in RFC #2985
181 240 : pub fn oid(&self) -> String {
182 240 : self.ptr.oid().to_string()
183 240 : }
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 110 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
272 110 : f.debug_struct("MsSpcStatementType")
273 110 : .field("oid", &self.oid())
274 110 : .finish()
275 110 : }
276 : }
277 :
278 : impl<'a> FromFFI<ffi::PE_MsSpcStatementType> for MsSpcStatementType<'a> {
279 110 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_MsSpcStatementType>) -> Self {
280 110 : Self {
281 110 : ptr,
282 110 : _owner: PhantomData,
283 110 : }
284 110 : }
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 110 : pub fn oid(&self) -> String {
293 110 : self.ptr.oid().to_string()
294 110 : }
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 240 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
401 240 : f.debug_struct("PKCS9MessageDigest").finish()
402 240 : }
403 : }
404 :
405 : impl PKCS9MessageDigest<'_> {
406 : /// Message digeset as a blob of bytes as described in the RFC
407 240 : pub fn digest(&self) -> &[u8] {
408 240 : to_slice!(self.ptr.digest());
409 240 : }
410 : }
411 :
412 : impl<'a> FromFFI<ffi::PE_PKCS9MessageDigest> for PKCS9MessageDigest<'a> {
413 240 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_PKCS9MessageDigest>) -> Self {
414 240 : Self {
415 240 : ptr,
416 240 : _owner: PhantomData,
417 240 : }
418 240 : }
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 90 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
487 90 : f.debug_struct("SpcSpOpusInfo")
488 90 : .field("program_name", &self.program_name())
489 90 : .field("more_info", &self.more_info())
490 90 : .finish()
491 90 : }
492 : }
493 :
494 : impl<'a> FromFFI<ffi::PE_SpcSpOpusInfo> for SpcSpOpusInfo<'a> {
495 90 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_SpcSpOpusInfo>) -> Self {
496 90 : Self {
497 90 : ptr,
498 90 : _owner: PhantomData,
499 90 : }
500 90 : }
501 : }
502 :
503 : impl SpcSpOpusInfo<'_> {
504 : /// Program description provided by the publisher
505 90 : pub fn program_name(&self) -> String {
506 90 : self.ptr.program_name().to_string()
507 90 : }
508 :
509 : /// Other information such as an url
510 90 : pub fn more_info(&self) -> String {
511 90 : self.ptr.more_info().to_string()
512 90 : }
513 : }
514 :
515 : pub struct SpcRelaxedPeMarkerCheck<'a> {
516 : ptr: cxx::UniquePtr<ffi::PE_SpcRelaxedPeMarkerCheck>,
517 : _owner: PhantomData<&'a ffi::PE_SignerInfo>,
518 : }
519 :
520 : impl std::fmt::Debug for SpcRelaxedPeMarkerCheck<'_> {
521 0 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
522 0 : f.debug_struct("SpcRelaxedPeMarkerCheck")
523 0 : .finish()
524 0 : }
525 : }
526 :
527 : impl<'a> FromFFI<ffi::PE_SpcRelaxedPeMarkerCheck> for SpcRelaxedPeMarkerCheck<'a> {
528 0 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_SpcRelaxedPeMarkerCheck>) -> Self {
529 0 : Self {
530 0 : ptr,
531 0 : _owner: PhantomData,
532 0 : }
533 0 : }
534 : }
535 :
536 : impl SpcRelaxedPeMarkerCheck<'_> {
537 :
538 : }
539 :
540 :
541 : /// ```text
542 : /// SigningCertificateV2 ::= SEQUENCE {
543 : /// certs SEQUENCE OF ESSCertIDv2,
544 : /// policies SEQUENCE OF PolicyInformation OPTIONAL
545 : /// }
546 : ///
547 : /// ESSCertIDv2 ::= SEQUENCE {
548 : /// hashAlgorithm AlgorithmIdentifier DEFAULT {algorithm id-sha256},
549 : /// certHash OCTET STRING,
550 : /// issuerSerial IssuerSerial OPTIONAL
551 : /// }
552 : ///
553 : /// IssuerSerial ::= SEQUENCE {
554 : /// issuer GeneralNames,
555 : /// serialNumber CertificateSerialNumber
556 : /// }
557 : ///
558 : /// PolicyInformation ::= SEQUENCE {
559 : /// policyIdentifier OBJECT IDENTIFIER,
560 : /// policyQualifiers SEQUENCE SIZE (1..MAX) OF PolicyQualifierInfo OPTIONAL
561 : /// }
562 : /// ```
563 : pub struct SigningCertificateV2<'a> {
564 : ptr: cxx::UniquePtr<ffi::PE_SigningCertificateV2>,
565 : _owner: PhantomData<&'a ffi::PE_SignerInfo>,
566 : }
567 :
568 : impl std::fmt::Debug for SigningCertificateV2<'_> {
569 0 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
570 0 : f.debug_struct("SigningCertificateV2")
571 0 : .finish()
572 0 : }
573 : }
574 :
575 : impl<'a> FromFFI<ffi::PE_SigningCertificateV2> for SigningCertificateV2<'a> {
576 30 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_SigningCertificateV2>) -> Self {
577 30 : Self {
578 30 : ptr,
579 30 : _owner: PhantomData,
580 30 : }
581 30 : }
582 : }
583 :
584 : impl SigningCertificateV2<'_> {
585 : // TODO(romain): Add API
586 : }
587 :
588 : /// This structure exposes the MS Counter Signature attribute
589 : pub struct MsCounterSign<'a> {
590 : ptr: cxx::UniquePtr<ffi::PE_MsCounterSign>,
591 : _owner: PhantomData<&'a ffi::PE_SignerInfo>,
592 : }
593 :
594 : impl std::fmt::Debug for MsCounterSign<'_> {
595 0 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
596 0 : f.debug_struct("MsCounterSign")
597 0 : .finish()
598 0 : }
599 : }
600 :
601 : impl<'a> FromFFI<ffi::PE_MsCounterSign> for MsCounterSign<'a> {
602 60 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_MsCounterSign>) -> Self {
603 60 : Self {
604 60 : ptr,
605 60 : _owner: PhantomData,
606 60 : }
607 60 : }
608 : }
609 :
610 : impl<'a> MsCounterSign<'a> {
611 0 : pub fn version(&self) -> u32 {
612 0 : self.ptr.version()
613 0 : }
614 :
615 0 : pub fn digest_algorithm(&self) -> Algorithms {
616 0 : Algorithms::from(self.ptr.digest_algorithm())
617 0 : }
618 :
619 : /// ContentInfo as described in the RFC2315 <https://tools.ietf.org/html/rfc2315#section-7>
620 120 : pub fn content_info(&'a self) -> ContentInfo<'a> {
621 120 : ContentInfo::from_ffi(self.ptr.content_info())
622 120 : }
623 :
624 : /// Return list of [`crate::pe::signature::X509`] certificates associated with this signature
625 60 : pub fn certificates(&'a self) -> MsCounterCertificates<'a> {
626 60 : MsCounterCertificates::new(self.ptr.certificates())
627 60 : }
628 :
629 : /// Iterator over the signer [`SignerInfo`] defined in the PKCS #7 signature
630 60 : pub fn signers(&'a self) -> MsCounterSigners<'a> {
631 60 : MsCounterSigners::new(self.ptr.signers())
632 60 : }
633 : }
634 :
635 100 : declare_iterator!(
636 100 : MsCounterCertificates,
637 100 : X509<'a>,
638 100 : ffi::PE_x509,
639 100 : ffi::PE_MsCounterSign,
640 100 : ffi::PE_MsCounterSign_it_certificates
641 100 : );
642 :
643 60 : declare_iterator!(
644 60 : MsCounterSigners,
645 60 : SignerInfo<'a>,
646 60 : ffi::PE_SignerInfo,
647 60 : ffi::PE_MsCounterSign,
648 60 : ffi::PE_MsCounterSign_it_signers
649 60 : );
650 :
651 : /// Interface over the structure described by the OID `1.3.6.1.4.1.311.10.3.28` (szOID_PLATFORM_MANIFEST_BINARY_ID)
652 : ///
653 : /// The internal structure is not documented but we can infer the following structure:
654 : ///
655 : /// ```text
656 : /// szOID_PLATFORM_MANIFEST_BINARY_ID ::= SET OF BinaryID
657 : /// ```
658 : ///
659 : /// `BinaryID` being an alias of UTF8STRING
660 : pub struct MsManifestBinaryID<'a> {
661 : ptr: cxx::UniquePtr<ffi::PE_MsManifestBinaryID>,
662 : _owner: PhantomData<&'a ffi::PE_SignerInfo>,
663 : }
664 :
665 : impl std::fmt::Debug for MsManifestBinaryID<'_> {
666 0 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
667 0 : f.debug_struct("MsManifestBinaryID")
668 0 : .field("manifest_id", &self.manifest_id())
669 0 : .finish()
670 0 : }
671 : }
672 :
673 : impl<'a> FromFFI<ffi::PE_MsManifestBinaryID> for MsManifestBinaryID<'a> {
674 10 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_MsManifestBinaryID>) -> Self {
675 10 : Self {
676 10 : ptr,
677 10 : _owner: PhantomData,
678 10 : }
679 10 : }
680 : }
681 :
682 : impl MsManifestBinaryID<'_> {
683 10 : pub fn manifest_id(&self) -> String {
684 10 : self.ptr.manifest_id().to_string()
685 10 : }
686 : }
|