Skip to content

Commit

Permalink
v0.1.2
Browse files Browse the repository at this point in the history
- Fix #1.
- Fix tstinfo with malformed generalizedtime.
- Expand the Windows-built trusted root certificate to cacert.pem.
- Fix other.
  • Loading branch information
REinject committed Sep 11, 2024
1 parent 54939dd commit 046778a
Show file tree
Hide file tree
Showing 16 changed files with 5,138 additions and 71 deletions.
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pe-sign"
version = "0.1.1"
version = "0.1.2"
edition = "2021"
authors = ["REinject"]
homepage = "https://github.com/0xlane/pe-sign"
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Download the binary for your platform from the Releases page. On Linux and macOS
### Usage

```powershell
pe-sign (0.1.1) - REinject
pe-sign (0.1.2) - REinject
A tool for parsing and verifing PE file signatures
Repository: https://github.com/0xlane/pe-sign
Expand Down
2 changes: 1 addition & 1 deletion README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
### 使用说明

```powershell
pe-sign (0.1.1) - REinject
pe-sign (0.1.2) - REinject
A tool for parsing and verifing PE file signatures
Repository: https://github.com/0xlane/pe-sign
Expand Down
84 changes: 79 additions & 5 deletions src/asn1_types.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,15 @@
use cms::cert::x509::spki::AlgorithmIdentifierOwned;
use cms::{
content_info::CmsVersion,
signed_data::{DigestAlgorithmIdentifiers, EncapsulatedContentInfo, SignerInfos},
};
use der::{
asn1::{GeneralizedTime, OctetString},
asn1::{GeneralizedTime, OctetString, SetOfVec},
oid::ObjectIdentifier,
Any, Enumerated, Sequence, ValueOrd,
Any, Decode, Enumerated, Sequence, ValueOrd,
};
use x509_cert::{
ext::Extensions, impl_newtype, serial_number::SerialNumber, spki::AlgorithmIdentifierOwned,
};
use x509_cert::{ext::Extensions, serial_number::SerialNumber};

pub const ID_SPC_INDIRECT_DATA: ObjectIdentifier =
ObjectIdentifier::new_unwrap("1.3.6.1.4.1.311.2.1.4");
Expand Down Expand Up @@ -42,13 +47,25 @@ pub struct SpcIndirectDataContent {
pub message_digest: DigestInfo,
}

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

impl TSTInfo {
pub fn get_gen_time(self: &Self) -> Result<GeneralizedTime, der::Error> {
let value = self.gen_time.value();
if value.len() > 15 {
let mut fix_value = vec![0x18, 0x0F];
fix_value.extend(&value[..14]);
fix_value.extend(&[b'Z']);

Ok(GeneralizedTime::from_der(&fix_value)?)
} else {
Ok(GeneralizedTime::from_der(&value)?)
}
}
}

#[derive(Clone, Debug, Copy, PartialEq, Eq, PartialOrd, Ord, Enumerated)]
#[asn1(type = "INTEGER")]
#[repr(u8)]
Expand All @@ -74,3 +106,45 @@ pub struct MessageImprint {
pub hash_algorithm: AlgorithmIdentifierOwned,
pub hashed_message: OctetString,
}

/// Alternative SignedData decoder that tolerates v1 attribute certificates.
///
/// For some bizarre reason, the SignedData used for the timestamp includes v1 attribute certs (!!!),
/// which are marked as obsolete in CMS and are not supported in the cms crate.
///
/// References from https://github.com/carl-wallace/tpm_cab_verify/blob/main/src/asn1.rs#L23.
#[derive(Clone, Debug, Eq, PartialEq, Sequence)]
#[allow(missing_docs)]
pub(crate) struct SignedData {
pub version: CmsVersion,
pub digest_algorithms: DigestAlgorithmIdentifiers,
pub encap_content_info: EncapsulatedContentInfo,
//todo consider defer decoding certs and CRLs
#[asn1(context_specific = "0", tag_mode = "IMPLICIT", optional = "true")]
pub certificates: Option<AnySet>,
#[asn1(context_specific = "1", tag_mode = "IMPLICIT", optional = "true")]
pub crls: Option<AnySet>,
pub signer_infos: SignerInfos,
}

/// Used in lieu of full support for all certificate and CRL types
#[derive(Clone, Eq, PartialEq, Debug)]
pub(crate) struct AnySet(pub SetOfVec<Any>);
impl_newtype!(AnySet, SetOfVec<Any>);

#[cfg(test)]
mod test {
use der::Decode;

use super::TSTInfo;

#[test]
fn test_tstinfo_with_malformed_generalizedtime() {
let tstinfo = TSTInfo::from_der(include_bytes!(
"./examples/tstinfo_with_malformed_generalizedtime.bin"
))
.unwrap();

assert!(tstinfo.get_gen_time().is_ok());
}
}
Loading

0 comments on commit 046778a

Please sign in to comment.