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 1536 : fn from_ffi(ffi_entry: cxx::UniquePtr<ffi::PE_Attribute>) -> Self {
48 1536 : unsafe {
49 1536 : let cmd_ref = ffi_entry.as_ref().unwrap();
50 1536 :
51 1536 : if ffi::PE_ContentType::classof(cmd_ref) {
52 360 : let raw = {
53 360 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
54 360 : type To = cxx::UniquePtr<ffi::PE_ContentType>;
55 360 : std::mem::transmute::<From, To>(ffi_entry)
56 360 : };
57 360 : Attribute::ContentType(ContentType::from_ffi(raw))
58 1176 : } else if ffi::PE_MsSpcNestedSignature::classof(cmd_ref) {
59 36 : let raw = {
60 36 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
61 36 : type To = cxx::UniquePtr<ffi::PE_MsSpcNestedSignature>;
62 36 : std::mem::transmute::<From, To>(ffi_entry)
63 36 : };
64 36 : Attribute::MsSpcNestedSignature(MsSpcNestedSignature::from_ffi(raw))
65 1140 : } else if ffi::PE_MsSpcStatementType::classof(cmd_ref) {
66 168 : let raw = {
67 168 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
68 168 : type To = cxx::UniquePtr<ffi::PE_MsSpcStatementType>;
69 168 : std::mem::transmute::<From, To>(ffi_entry)
70 168 : };
71 168 : Attribute::MsSpcStatementType(MsSpcStatementType::from_ffi(raw))
72 972 : } else if ffi::PE_PKCS9AtSequenceNumber::classof(cmd_ref) {
73 24 : let raw = {
74 24 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
75 24 : type To = cxx::UniquePtr<ffi::PE_PKCS9AtSequenceNumber>;
76 24 : std::mem::transmute::<From, To>(ffi_entry)
77 24 : };
78 24 : Attribute::PKCS9AtSequenceNumber(PKCS9AtSequenceNumber::from_ffi(raw))
79 948 : } else if ffi::PE_PKCS9CounterSignature::classof(cmd_ref) {
80 60 : let raw = {
81 60 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
82 60 : type To = cxx::UniquePtr<ffi::PE_PKCS9CounterSignature>;
83 60 : std::mem::transmute::<From, To>(ffi_entry)
84 60 : };
85 60 : Attribute::PKCS9CounterSignature(PKCS9CounterSignature::from_ffi(raw))
86 888 : } else if ffi::PE_PKCS9MessageDigest::classof(cmd_ref) {
87 360 : let raw = {
88 360 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
89 360 : type To = cxx::UniquePtr<ffi::PE_PKCS9MessageDigest>;
90 360 : std::mem::transmute::<From, To>(ffi_entry)
91 360 : };
92 360 : Attribute::PKCS9MessageDigest(PKCS9MessageDigest::from_ffi(raw))
93 528 : } else if ffi::PE_PKCS9SigningTime::classof(cmd_ref) {
94 132 : let raw = {
95 132 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
96 132 : type To = cxx::UniquePtr<ffi::PE_PKCS9SigningTime>;
97 132 : std::mem::transmute::<From, To>(ffi_entry)
98 132 : };
99 132 : Attribute::PKCS9SigningTime(PKCS9SigningTime::from_ffi(raw))
100 396 : } else if ffi::PE_SpcSpOpusInfo::classof(cmd_ref) {
101 144 : let raw = {
102 144 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
103 144 : type To = cxx::UniquePtr<ffi::PE_SpcSpOpusInfo>;
104 144 : std::mem::transmute::<From, To>(ffi_entry)
105 144 : };
106 144 : Attribute::SpcSpOpusInfo(SpcSpOpusInfo::from_ffi(raw))
107 252 : } else if ffi::PE_MsManifestBinaryID::classof(cmd_ref) {
108 12 : let raw = {
109 12 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
110 12 : type To = cxx::UniquePtr<ffi::PE_MsManifestBinaryID>;
111 12 : std::mem::transmute::<From, To>(ffi_entry)
112 12 : };
113 12 : Attribute::MsManifestBinaryID(MsManifestBinaryID::from_ffi(raw))
114 240 : } else if ffi::PE_MsCounterSign::classof(cmd_ref) {
115 108 : let raw = {
116 108 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
117 108 : type To = cxx::UniquePtr<ffi::PE_MsCounterSign>;
118 108 : std::mem::transmute::<From, To>(ffi_entry)
119 108 : };
120 108 : Attribute::MsCounterSign(MsCounterSign::from_ffi(raw))
121 132 : } else if ffi::PE_SpcRelaxedPeMarkerCheck::classof(cmd_ref) {
122 24 : let raw = {
123 24 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
124 24 : type To = cxx::UniquePtr<ffi::PE_SpcRelaxedPeMarkerCheck>;
125 24 : std::mem::transmute::<From, To>(ffi_entry)
126 24 : };
127 24 : Attribute::SpcRelaxedPeMarkerCheck(SpcRelaxedPeMarkerCheck::from_ffi(raw))
128 108 : } else if ffi::PE_SigningCertificateV2::classof(cmd_ref) {
129 72 : let raw = {
130 72 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
131 72 : type To = cxx::UniquePtr<ffi::PE_SigningCertificateV2>;
132 72 : std::mem::transmute::<From, To>(ffi_entry)
133 72 : };
134 72 : Attribute::SigningCertificateV2(SigningCertificateV2::from_ffi(raw))
135 : } else {
136 36 : assert!(
137 36 : ffi::PE_GenericType::classof(cmd_ref),
138 0 : "Must be a GenericType node"
139 : );
140 36 : let raw = {
141 36 : type From = cxx::UniquePtr<ffi::PE_Attribute>;
142 36 : type To = cxx::UniquePtr<ffi::PE_GenericType>;
143 36 : std::mem::transmute::<From, To>(ffi_entry)
144 36 : };
145 36 : Attribute::GenericType(GenericType::from_ffi(raw))
146 : }
147 : }
148 1536 : }
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 360 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
164 360 : f.debug_struct("ContentType")
165 360 : .field("oid", &self.oid())
166 360 : .finish()
167 360 : }
168 : }
169 :
170 : impl<'a> FromFFI<ffi::PE_ContentType> for ContentType<'a> {
171 360 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_ContentType>) -> Self {
172 360 : Self {
173 360 : ptr,
174 360 : _owner: PhantomData,
175 360 : }
176 360 : }
177 : }
178 :
179 : impl ContentType<'_> {
180 : /// OID as described in RFC #2985
181 360 : pub fn oid(&self) -> String {
182 360 : self.ptr.oid().to_string()
183 360 : }
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 36 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
194 36 : f.debug_struct("GenericType")
195 36 : .field("oid", &self.oid())
196 36 : .finish()
197 36 : }
198 : }
199 :
200 : impl<'a> FromFFI<ffi::PE_GenericType> for GenericType<'a> {
201 36 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_GenericType>) -> Self {
202 36 : Self {
203 36 : ptr,
204 36 : _owner: PhantomData,
205 36 : }
206 36 : }
207 : }
208 :
209 : impl GenericType<'_> {
210 : /// OID of the original attribute
211 36 : pub fn oid(&self) -> String {
212 36 : self.ptr.oid().to_string()
213 36 : }
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 36 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
237 36 : f.debug_struct("MsSpcNestedSignature").finish()
238 36 : }
239 : }
240 :
241 : impl<'a> FromFFI<ffi::PE_MsSpcNestedSignature> for MsSpcNestedSignature<'a> {
242 36 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_MsSpcNestedSignature>) -> Self {
243 36 : Self {
244 36 : ptr,
245 36 : _owner: PhantomData,
246 36 : }
247 36 : }
248 : }
249 :
250 : impl MsSpcNestedSignature<'_> {
251 : /// Underlying Signature object
252 36 : pub fn signature(&self) -> Signature {
253 36 : Signature::from_ffi(self.ptr.sig())
254 36 : }
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 168 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
272 168 : f.debug_struct("MsSpcStatementType")
273 168 : .field("oid", &self.oid())
274 168 : .finish()
275 168 : }
276 : }
277 :
278 : impl<'a> FromFFI<ffi::PE_MsSpcStatementType> for MsSpcStatementType<'a> {
279 168 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_MsSpcStatementType>) -> Self {
280 168 : Self {
281 168 : ptr,
282 168 : _owner: PhantomData,
283 168 : }
284 168 : }
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 168 : pub fn oid(&self) -> String {
293 168 : self.ptr.oid().to_string()
294 168 : }
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 24 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
319 24 : f.debug_struct("PKCS9AtSequenceNumber")
320 24 : .field("number", &self.number())
321 24 : .finish()
322 24 : }
323 : }
324 :
325 : impl PKCS9AtSequenceNumber<'_> {
326 : //! Number as described in the RFC
327 24 : pub fn number(&self) -> u32 {
328 24 : self.ptr.number()
329 24 : }
330 : }
331 :
332 : impl<'a> FromFFI<ffi::PE_PKCS9AtSequenceNumber> for PKCS9AtSequenceNumber<'a> {
333 24 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_PKCS9AtSequenceNumber>) -> Self {
334 24 : Self {
335 24 : ptr,
336 24 : _owner: PhantomData,
337 24 : }
338 24 : }
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 60 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
359 60 : f.debug_struct("PKCS9CounterSignature").finish()
360 60 : }
361 : }
362 :
363 : impl<'a> FromFFI<ffi::PE_PKCS9CounterSignature> for PKCS9CounterSignature<'a> {
364 60 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_PKCS9CounterSignature>) -> Self {
365 60 : Self {
366 60 : ptr,
367 60 : _owner: PhantomData,
368 60 : }
369 60 : }
370 : }
371 :
372 : impl PKCS9CounterSignature<'_> {
373 : /// SignerInfo as described in the RFC #2985
374 60 : pub fn signer(&self) -> SignerInfo {
375 60 : SignerInfo::from_ffi(self.ptr.signer())
376 60 : }
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 360 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
401 360 : f.debug_struct("PKCS9MessageDigest").finish()
402 360 : }
403 : }
404 :
405 : impl PKCS9MessageDigest<'_> {
406 : /// Message digeset as a blob of bytes as described in the RFC
407 360 : pub fn digest(&self) -> &[u8] {
408 360 : to_slice!(self.ptr.digest());
409 360 : }
410 : }
411 :
412 : impl<'a> FromFFI<ffi::PE_PKCS9MessageDigest> for PKCS9MessageDigest<'a> {
413 360 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_PKCS9MessageDigest>) -> Self {
414 360 : Self {
415 360 : ptr,
416 360 : _owner: PhantomData,
417 360 : }
418 360 : }
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 132 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
443 132 : f.debug_struct("PKCS9SigningTime")
444 132 : .field("time", &self.time())
445 132 : .finish()
446 132 : }
447 : }
448 :
449 : impl<'a> FromFFI<ffi::PE_PKCS9SigningTime> for PKCS9SigningTime<'a> {
450 132 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_PKCS9SigningTime>) -> Self {
451 132 : Self {
452 132 : ptr,
453 132 : _owner: PhantomData,
454 132 : }
455 132 : }
456 : }
457 :
458 : impl PKCS9SigningTime<'_> {
459 : /// Time as a tuple: `(year, month, day, hour, min, sec)`
460 132 : pub fn time(&self) -> (u64, u64, u64, u64, u64, u64) {
461 132 : let vec = Vec::from(self.ptr.time().as_slice());
462 132 : if vec.len() != 6 {
463 0 : return (0, 0, 0, 0, 0, 0);
464 132 : }
465 132 : (vec[0], vec[1], vec[2], vec[3], vec[4], vec[5])
466 132 : }
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 144 : fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
487 144 : f.debug_struct("SpcSpOpusInfo")
488 144 : .field("program_name", &self.program_name())
489 144 : .field("more_info", &self.more_info())
490 144 : .finish()
491 144 : }
492 : }
493 :
494 : impl<'a> FromFFI<ffi::PE_SpcSpOpusInfo> for SpcSpOpusInfo<'a> {
495 144 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_SpcSpOpusInfo>) -> Self {
496 144 : Self {
497 144 : ptr,
498 144 : _owner: PhantomData,
499 144 : }
500 144 : }
501 : }
502 :
503 : impl SpcSpOpusInfo<'_> {
504 : /// Program description provided by the publisher
505 144 : pub fn program_name(&self) -> String {
506 144 : self.ptr.program_name().to_string()
507 144 : }
508 :
509 : /// Other information such as an url
510 144 : pub fn more_info(&self) -> String {
511 144 : self.ptr.more_info().to_string()
512 144 : }
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 24 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_SpcRelaxedPeMarkerCheck>) -> Self {
530 24 : Self {
531 24 : ptr,
532 24 : _owner: PhantomData,
533 24 : }
534 24 : }
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 72 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_SigningCertificateV2>) -> Self {
579 72 : Self {
580 72 : ptr,
581 72 : _owner: PhantomData,
582 72 : }
583 72 : }
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 108 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_MsCounterSign>) -> Self {
605 108 : Self {
606 108 : ptr,
607 108 : _owner: PhantomData,
608 108 : }
609 108 : }
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 216 : pub fn content_info(&'a self) -> ContentInfo<'a> {
623 216 : ContentInfo::from_ffi(self.ptr.content_info())
624 216 : }
625 :
626 : /// Return list of [`crate::pe::signature::X509`] certificates associated with this signature
627 108 : pub fn certificates(&'a self) -> MsCounterCertificates<'a> {
628 108 : MsCounterCertificates::new(self.ptr.certificates())
629 108 : }
630 :
631 : /// Iterator over the signer [`SignerInfo`] defined in the PKCS #7 signature
632 108 : pub fn signers(&'a self) -> MsCounterSigners<'a> {
633 108 : MsCounterSigners::new(self.ptr.signers())
634 108 : }
635 : }
636 :
637 192 : declare_iterator!(
638 192 : MsCounterCertificates,
639 192 : X509<'a>,
640 192 : ffi::PE_x509,
641 192 : ffi::PE_MsCounterSign,
642 192 : ffi::PE_MsCounterSign_it_certificates
643 192 : );
644 :
645 108 : declare_iterator!(
646 108 : MsCounterSigners,
647 108 : SignerInfo<'a>,
648 108 : ffi::PE_SignerInfo,
649 108 : ffi::PE_MsCounterSign,
650 108 : ffi::PE_MsCounterSign_it_signers
651 108 : );
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 12 : fn from_ffi(ptr: cxx::UniquePtr<ffi::PE_MsManifestBinaryID>) -> Self {
677 12 : Self {
678 12 : ptr,
679 12 : _owner: PhantomData,
680 12 : }
681 12 : }
682 : }
683 :
684 : impl MsManifestBinaryID<'_> {
685 12 : pub fn manifest_id(&self) -> String {
686 12 : self.ptr.manifest_id().to_string()
687 12 : }
688 : }
|