Skip to content

Commit 046778a

Browse files
author
REinject
committed
v0.1.2
- Fix #1. - Fix tstinfo with malformed generalizedtime. - Expand the Windows-built trusted root certificate to cacert.pem. - Fix other.
1 parent 54939dd commit 046778a

16 files changed

+5138
-71
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "pe-sign"
3-
version = "0.1.1"
3+
version = "0.1.2"
44
edition = "2021"
55
authors = ["REinject"]
66
homepage = "https://github.com/0xlane/pe-sign"

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ Download the binary for your platform from the Releases page. On Linux and macOS
3131
### Usage
3232

3333
```powershell
34-
pe-sign (0.1.1) - REinject
34+
pe-sign (0.1.2) - REinject
3535
A tool for parsing and verifing PE file signatures
3636
3737
Repository: https://github.com/0xlane/pe-sign

README_zh.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
### 使用说明
3232

3333
```powershell
34-
pe-sign (0.1.1) - REinject
34+
pe-sign (0.1.2) - REinject
3535
A tool for parsing and verifing PE file signatures
3636
3737
Repository: https://github.com/0xlane/pe-sign

src/asn1_types.rs

Lines changed: 79 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
1-
use cms::cert::x509::spki::AlgorithmIdentifierOwned;
1+
use cms::{
2+
content_info::CmsVersion,
3+
signed_data::{DigestAlgorithmIdentifiers, EncapsulatedContentInfo, SignerInfos},
4+
};
25
use der::{
3-
asn1::{GeneralizedTime, OctetString},
6+
asn1::{GeneralizedTime, OctetString, SetOfVec},
47
oid::ObjectIdentifier,
5-
Any, Enumerated, Sequence, ValueOrd,
8+
Any, Decode, Enumerated, Sequence, ValueOrd,
9+
};
10+
use x509_cert::{
11+
ext::Extensions, impl_newtype, serial_number::SerialNumber, spki::AlgorithmIdentifierOwned,
612
};
7-
use x509_cert::{ext::Extensions, serial_number::SerialNumber};
813

914
pub const ID_SPC_INDIRECT_DATA: ObjectIdentifier =
1015
ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.2.1.4");
@@ -42,13 +47,25 @@ pub struct SpcIndirectDataContent {
4247
pub message_digest: DigestInfo,
4348
}
4449

50+
/// Timestamps on TrustedTpm.cab feature mis-encoded GeneralizedTime values, as shown in this dump
51+
/// generated using dumpasn1:
52+
///
53+
/// ```text
54+
/// 4477 19: GeneralizedTime '20240614203756.847Z'
55+
/// : Error: Time is encoded incorrectly.
56+
///```
57+
///
58+
/// This structure treats the time field as an Any, which at least allows the message digest to be
59+
/// compared.
60+
///
61+
/// References from https://github.com/carl-wallace/tpm_cab_verify/blob/main/src/asn1.rs#L39C1-L48C14
4562
#[derive(Clone, Debug, Eq, PartialEq, Sequence)]
4663
pub struct TSTInfo {
4764
pub version: TSTVersion,
4865
pub policy: ObjectIdentifier,
4966
pub message_imprint: MessageImprint,
5067
pub serial_number: SerialNumber,
51-
pub gen_time: GeneralizedTime,
68+
pub gen_time: Any,
5269
#[asn1(optional = "true")]
5370
pub accuracy: Option<Any>,
5471
#[asn1(optional = "true")]
@@ -61,6 +78,21 @@ pub struct TSTInfo {
6178
pub extensions: Option<Extensions>,
6279
}
6380

81+
impl TSTInfo {
82+
pub fn get_gen_time(self: &Self) -> Result<GeneralizedTime, der::Error> {
83+
let value = self.gen_time.value();
84+
if value.len() > 15 {
85+
let mut fix_value = vec![0x18, 0x0F];
86+
fix_value.extend(&value[..14]);
87+
fix_value.extend(&[b'Z']);
88+
89+
Ok(GeneralizedTime::from_der(&fix_value)?)
90+
} else {
91+
Ok(GeneralizedTime::from_der(&value)?)
92+
}
93+
}
94+
}
95+
6496
#[derive(Clone, Debug, Copy, PartialEq, Eq, PartialOrd, Ord, Enumerated)]
6597
#[asn1(type = "INTEGER")]
6698
#[repr(u8)]
@@ -74,3 +106,45 @@ pub struct MessageImprint {
74106
pub hash_algorithm: AlgorithmIdentifierOwned,
75107
pub hashed_message: OctetString,
76108
}
109+
110+
/// Alternative SignedData decoder that tolerates v1 attribute certificates.
111+
///
112+
/// For some bizarre reason, the SignedData used for the timestamp includes v1 attribute certs (!!!),
113+
/// which are marked as obsolete in CMS and are not supported in the cms crate.
114+
///
115+
/// References from https://github.com/carl-wallace/tpm_cab_verify/blob/main/src/asn1.rs#L23.
116+
#[derive(Clone, Debug, Eq, PartialEq, Sequence)]
117+
#[allow(missing_docs)]
118+
pub(crate) struct SignedData {
119+
pub version: CmsVersion,
120+
pub digest_algorithms: DigestAlgorithmIdentifiers,
121+
pub encap_content_info: EncapsulatedContentInfo,
122+
//todo consider defer decoding certs and CRLs
123+
#[asn1(context_specific = "0", tag_mode = "IMPLICIT", optional = "true")]
124+
pub certificates: Option<AnySet>,
125+
#[asn1(context_specific = "1", tag_mode = "IMPLICIT", optional = "true")]
126+
pub crls: Option<AnySet>,
127+
pub signer_infos: SignerInfos,
128+
}
129+
130+
/// Used in lieu of full support for all certificate and CRL types
131+
#[derive(Clone, Eq, PartialEq, Debug)]
132+
pub(crate) struct AnySet(pub SetOfVec<Any>);
133+
impl_newtype!(AnySet, SetOfVec<Any>);
134+
135+
#[cfg(test)]
136+
mod test {
137+
use der::Decode;
138+
139+
use super::TSTInfo;
140+
141+
#[test]
142+
fn test_tstinfo_with_malformed_generalizedtime() {
143+
let tstinfo = TSTInfo::from_der(include_bytes!(
144+
"./examples/tstinfo_with_malformed_generalizedtime.bin"
145+
))
146+
.unwrap();
147+
148+
assert!(tstinfo.get_gen_time().is_ok());
149+
}
150+
}

0 commit comments

Comments
 (0)