Skip to content

Rfc3161TimestampToken.TryDecode does not work for timestamps in Windows OS libraries Authenticode signatures #62307

@bartonjs

Description

@bartonjs

If you take the Authenticode signature payload from (e.g.) ntdll.dll, decode that as a SignedCms, and try to interpret cms.SignerInfos[0].UnsignedAttributes[0].Values[0] (the only instance of the only unsigned attribute of the only signer) as an Rfc3161TimeStampToken, TryDecode returns false.

Stepping through, the first failure occurs because the TimestampToken contains a certificate of a type other than X.509 public key certificates (namely, an X.509 attribute certificate, v1).

After confirming Windows behaviors in the CryptMsg* APIs for how unsupported certificate formats are treated, I made the changes locally to get past this point. The branch https://github.com/bartonjs/runtime/tree/authenticode_rfc3161 contains those changes (and some unrelated test refactoring changes in earlier commits).

Unfortunately, that doesn't solve the issue.

RFC 3161, section 2.3 says

2.3. Identification of the TSA

   The TSA MUST sign each time-stamp message with a key reserved
   specifically for that purpose.  A TSA MAY have distinct private keys,
   e.g., to accommodate different policies, different algorithms,
   different private key sizes or to increase the performance.  The
   corresponding certificate MUST contain only one instance of the
   extended key usage field extension as defined in [RFC2459] Section
   4.2.1.13 with KeyPurposeID having value:

   id-kp-timeStamping.  This extension MUST be critical.

   The following object identifier identifies the KeyPurposeID having
   value id-kp-timeStamping.

   id-kp-timeStamping OBJECT IDENTIFIER ::= {iso(1)
                   identified-organization(3) dod(6)
                   internet(1) security(5) mechanisms(5) pkix(7)
                   kp (3) timestamping (8)}

(specifically: This extension MUST be critical.)

And the relevant TSA certificate is non-conforming, the EKU extension is not marked critical.

Since the spec said it, we check for it:

The fact that Windows considers the timestamp valid suggests that the OS must not care about that particular sentence, and must not perform that particular check. So maybe we should relax that check for industry conformance (or come up with some other mode/opt-in). (FWIW, I haven't independently verified that the OS thinks the timestamp is valid, just taken it on word of mouth and faith.)

Leaving the notes here so others have the option of weighing in on how we handle the non-conforming TSA cert.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions