rasn_cms/
authenticode.rs

1//! Windows Authenticode Portable Executable Signature Format
2//!
3//! Authenticode is a digital signature format that is used to determine the origin and integrity of
4//! software binaries. Authenticode is based on Public-Key Cryptography Standards (PKCS) #7 signed
5//! data and X.509 certificates to bind an Authenticode-signed binary to the identity of a software
6//! publisher.
7//!
8//! An Authenticode signature's ContentInfo structure contains several structures that in turn contain
9//! the file's hash value, page hash values (if present), the file description, and various optional or legacy
10//! ASN.1 fields.
11//!
12//! Reference: [Windows Authenticode Portable Executable Signature Format](http://msdn.microsoft.com/en-US/windows/hardware/gg463183)
13//! **NOTE**: the document differs from the actual implementation. This crate contains the structures used in actual signing.
14use core::ops::{BitAnd, BitAndAssign, BitOr, BitOrAssign, Neg};
15
16use rasn::prelude::*;
17use rasn_pkix::AlgorithmIdentifier;
18
19pub const SPC_INDIRECT_DATA_OBJID: &Oid = Oid::ISO_IDENTIFIED_ORGANISATION_DOD_INTERNET_PRIVATE_ENTERPRISES_MICROSOFT_SPC_INDIRECT_DATA_OBJID;
20pub const SPC_PE_IMAGE_DATA_OBJID: &Oid = Oid::ISO_IDENTIFIED_ORGANISATION_DOD_INTERNET_PRIVATE_ENTERPRISES_MICROSOFT_SPC_PE_IMAGE_DATA_OBJID;
21pub const SPC_SP_OPUS_INFO_OBJID: &Oid = Oid::ISO_IDENTIFIED_ORGANISATION_DOD_INTERNET_PRIVATE_ENTERPRISES_MICROSOFT_SPC_SP_OPUS_INFO_OBJID;
22pub const SPC_STATEMENT_TYPE_OBJID: &Oid = Oid::ISO_IDENTIFIED_ORGANISATION_DOD_INTERNET_PRIVATE_ENTERPRISES_MICROSOFT_SPC_STATEMENT_TYPE_OBJID;
23pub const SPC_CAB_DATA_OBJID: &Oid =
24    Oid::ISO_IDENTIFIED_ORGANISATION_DOD_INTERNET_PRIVATE_ENTERPRISES_MICROSOFT_SPC_CAB_DATA_OBJID;
25pub const SPC_SIPINFO_OBJID: &Oid =
26    Oid::ISO_IDENTIFIED_ORGANISATION_DOD_INTERNET_PRIVATE_ENTERPRISES_MICROSOFT_SPC_SIPINFO_OBJID;
27pub const SPC_PE_IMAGE_PAGE_HASHES_V1: &Oid = Oid::ISO_IDENTIFIED_ORGANISATION_DOD_INTERNET_PRIVATE_ENTERPRISES_MICROSOFT_SPC_PE_IMAGE_PAGE_HASHES_V1;
28pub const SPC_PE_IMAGE_PAGE_HASHES_V2: &Oid = Oid::ISO_IDENTIFIED_ORGANISATION_DOD_INTERNET_PRIVATE_ENTERPRISES_MICROSOFT_SPC_PE_IMAGE_PAGE_HASHES_V2;
29pub const SPC_NESTED_SIGNATURE_OBJID: &Oid = Oid::ISO_IDENTIFIED_ORGANISATION_DOD_INTERNET_PRIVATE_ENTERPRISES_MICROSOFT_SPC_NESTED_SIGNATURE_OBJID;
30pub const SPC_TIME_STAMP_REQUEST_OBJID: &Oid = Oid::ISO_IDENTIFIED_ORGANISATION_DOD_INTERNET_PRIVATE_ENTERPRISES_MICROSOFT_SPC_TIME_STAMP_REQUEST_OBJID;
31pub const SPC_RFC3161_OBJID: &Oid =
32    Oid::ISO_IDENTIFIED_ORGANISATION_DOD_INTERNET_PRIVATE_ENTERPRISES_MICROSOFT_SPC_RFC3161_OBJID;
33
34#[allow(clippy::declare_interior_mutable_const)]
35// Mutable const warning comes from external crate `bytes` FIXME
36pub const SPC_CLASS_UUID: OctetString = OctetString::from_static(&[
37    0xa6, 0xb5, 0x86, 0xd5, 0xb4, 0xa1, 0x24, 0x66, 0xae, 0x05, 0xa2, 0x17, 0xda, 0x8e, 0x60, 0xd6,
38]);
39
40pub type SpcUuid = OctetString;
41
42/// The root structure is SpcIndirectDataContent.
43#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
44pub struct SpcIndirectDataContent {
45    pub data: SpcAttributeTypeAndOptionalValue,
46    pub message_digest: DigestInfo,
47}
48
49/// The SpcAttributeTypeAndOptionalValue structure has two fields, which are set for an
50/// Authenticode-signed PE file.
51/// The attribute_type is set to SPC_PE_IMAGE_DATAOBJ OID (1.3.6.1.4.1.311.2.1.15)
52#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
53pub struct SpcAttributeTypeAndOptionalValue {
54    pub attribute_type: ObjectIdentifier,
55    pub value: Option<Any>,
56}
57
58/// The DigestInfo structure defines the digest algorithm and data
59#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
60pub struct DigestInfo {
61    pub digest_algorithm: AlgorithmIdentifier,
62    pub digest: OctetString,
63}
64
65/// The SpcPeImageData structure specifies which portions of the Windows PE file are hashed.
66#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
67pub struct SpcPeImageData {
68    pub flags: SpcPeImageFlags,
69    #[rasn(tag(explicit(0)))]
70    pub file: Option<SpcLink>,
71}
72
73/// Flags specify which portions of the Windows PE file are hashed.
74#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
75#[rasn(delegate)]
76pub struct SpcPeImageFlags(pub BitString);
77
78impl SpcPeImageFlags {
79    pub fn include_resources() -> Self {
80        Self(BitString::from_element(0))
81    }
82
83    pub fn include_debug_info() -> Self {
84        Self(BitString::from_element(1))
85    }
86
87    pub fn include_import_address_table() -> Self {
88        Self(BitString::from_element(2))
89    }
90}
91
92impl BitOr for SpcPeImageFlags {
93    type Output = Self;
94
95    fn bitor(self, rhs: Self) -> Self::Output {
96        Self(self.0 | rhs.0)
97    }
98}
99
100impl BitOrAssign for SpcPeImageFlags {
101    fn bitor_assign(&mut self, rhs: Self) {
102        self.0 |= rhs.0;
103    }
104}
105
106impl BitAnd for SpcPeImageFlags {
107    type Output = Self;
108
109    fn bitand(self, rhs: Self) -> Self::Output {
110        Self(self.0 & rhs.0)
111    }
112}
113
114impl BitAndAssign for SpcPeImageFlags {
115    fn bitand_assign(&mut self, rhs: Self) {
116        self.0 &= rhs.0;
117    }
118}
119
120impl Neg for SpcPeImageFlags {
121    type Output = Self;
122
123    fn neg(self) -> Self::Output {
124        Self(!self.0)
125    }
126}
127
128/// SPCLink originally contained information that describes the software publisher
129#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
130#[rasn(choice)]
131pub enum SpcLink {
132    #[rasn(tag(0))]
133    Url(Ia5String),
134    #[rasn(tag(1))]
135    Moniker(SpcSerializedObject),
136    #[rasn(tag(explicit(2)))]
137    File(SpcString),
138}
139
140/// SpcString is either Unicode or ASCII string
141#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
142#[rasn(choice)]
143pub enum SpcString {
144    #[rasn(tag(0))]
145    Unicode(BmpString),
146    #[rasn(tag(1))]
147    Ascii(Ia5String),
148}
149
150/// SpcSerializedObject contains a binary structure with page hashes
151#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
152pub struct SpcSerializedObject {
153    pub class_id: SpcUuid,
154    pub serialized_data: OctetString,
155}
156
157/// This structure is present in SignerInfo authenticated attributes.
158/// It is identified by SPC_SP_OPUS_INFO_OBJID (1.3.6.1.4.1.311.2.1.12)
159#[derive(AsnType, Clone, Debug, Decode, Encode, PartialEq, Eq, PartialOrd, Ord, Hash)]
160pub struct SpcSpOpusInfo {
161    #[rasn(tag(explicit(0)))]
162    pub program_name: Option<SpcString>,
163    #[rasn(tag(explicit(1)))]
164    pub more_info: Option<SpcLink>,
165}