Patch My PC / Blog

Demystifying Timestamping: Securing Scripts and CAB Files for WSUS, ConfigMgr, and Intune

by | Dec 12, 2024 | Blog

In this blog we’ll demystify timestamping, cover why it’s an important process in the management of third-party apps and updates in WSUS, ConfigMgr and WSUS, and how you can test it effectively.

When managing third-party applications and updates with tools like WSUS, ConfigMgr, and Intune is important to ensure the security and integrity of the files and scripts that you utilise. Digitally signing scripts and files with a code-signing certificate serves as their official badge of authenticity, verifying they come from a trusted source and haven’t been tampered with.

One, often overlooked, aspect of the signing process is timestamping. Timestamping is considered the “proof of age” for your signed scripts and files and ensures their authenticity remains valid even after the signing certificate itself expires.

What is Timestamping

Timestamping is a process that securely records the exact date and time when a file or script is signed. It works by embedding a timestamp, provided by a trusted Timestamp Authority (TSA), into the file or script’s digital signature. This ensures that the signature remains valid even if the signing certificate expires or is revoked.

The process relies on cryptographic methods to link the timestamp with the file or script’s signature, creating a tamper-proof record. When a file with a timestamped signature is verified, the timestamp confirms the integrity and authenticity of the file or script, regardless of the certificate’s current status. This makes timestamping essential for long-term trust and compliance, especially in environments where files may need to be validated years after they were signed.

In the image below you can see a CAB file signed and then counter-signed by a TSA.

Do we really need to Timestamp our stuff?

Granted, code-signing alone proves authenticity, but without timestamping, a file’s trustworthiness ends with the certificate’s validity period. Timestamping addresses this gap by preserving a snapshot of the file’s authenticity at the moment it was signed, often referred to as Long Term Validation (LTV). This means:

  • Files remain verifiable, reducing disruptions caused by expired certificates.
  • It is easy to distinguish between files or scripts signed before a certificate was revoked and those signed after, preventing misuse of compromised certificates.
  • Organizations can confidently rely on legacy updates and scripts without worrying about certificate expiration.

How does Timestamping work?

Here’s how the timestamping process typically works:

  1. File Signing – A cryptographic hash of the file (e.g. cab or ps1) is created.
  2. Timestamp Request – The hash is sent to a trusted Timestamp Authority (TSA) (e.g. http://timestamp.digicert.com).
  3. Timestamp Token – The TSA generates a timestamp token, signing it with its private key and appending the current date and time.
  4. Validation – The signed file now includes the timestamp, which can be validated using the TSA’s public key.
Timestamping flow

Timestamping with PowerShell

Those accustomed to PowerShell may already be familiar with the Set-AuthenticodeSignature cmdlet which can be used to code-sign scripts and files. We can also use the Get-AuthenticodeSignature cmdlet to view information about a signed script of file.

Alternatively, SignTool which comes with the Windows SDK can be quite useful to view and create digital signatures.

Note: If you want to experiment with Signtool, the Windows SDK can be downloaded from https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk

After installing the SDK, you can locate SignTool in the following directory:

C:\Program Files (x86)\Windows Kits\10\bin\<version>\<architecture>\signtool.exe

In the following example, we will use a code-signing certificate to sign a CAB file using the Set-AuthenticodeSignature cmdlet. The cmdlet does not directly support handling the .pfx from a path so we must import it as an X509Certificate2 object first. We will also use a well know TSA for the timestamping – http://timestamp.digicert.com.

# Variables
$pfxPath = "C:\temp\timestamp\temp_cert.pfx"
$pfxPassword = "1234"
$fileToSign = "C:\temp\timestamp\testfile.cab"
$timestampServer = "http://timestamp.digicert.com"

# Load the certificate
$securePassword = ConvertTo-SecureString -String $pfxPassword -AsPlainText -Force
$certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($pfxPath, $securePassword, [System.Security.Cryptography.X509Certificates.X509KeyStorageFlags]::Exportable)

# Sign the file with timestamp
Set-AuthenticodeSignature -FilePath $fileToSign -Certificate $certificate -TimestampServer $timestampServer

Signtool is really quite nice because it can handle the .pfx file directly, and accepts a plain password string, simplifying the command somewhat for testing.

# Variables
$signtoolPath = "C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64"
$pfxPath = "C:\temp\timestamp\temp_cert.pfx"
$pfxPassword = "1234"
$fileToSign = "C:\temp\timestamp\testfile.cab"
$timestampServer = "http://timestamp.digicert.com"

# Temporarily add signtool path to the env PATH for testing
$originalPath = $env:Path
$env:Path = "$signtoolPath;$env:Path"

# Build the signtool command
$signToolCmd = "`signtool.exe sign /f `"$pfxPath`" /p `$pfxPassword /t `$timestampServer /fd SHA256 /v `"$fileToSign`""
Invoke-Expression $signToolCmd

# Restore the original env PATH
$env:Path = $originalPath

Using either method, the result is a signed CAB file that has been timestamped (co-signed with the TSA private key).

Timestamped CAB file

We can also use the same approach for signing scripts. Just update the fileToSign variable in the previous code snippet to:-

$fileToSign = "C:\temp\timestamp\testscript.ps1"

When signing scripts, the Signature Block is evidence the script has been signed.

Note: If you edit the script AFTER the script has been signed, this signature is invalidated.

Patch My PC Publisher Timestamping

When it comes to digitally signing files and adding a timestamp to third-party updates using the Patch My PC Publisher, both the Publisher and Microsoft’s SignTool utility achieve the same core objective – ensuring file integrity and establishing the authenticity of the source. However, the methods differ slightly.

The Publisher explicitly interacts with the Windows cryptographic API, specifically the CryptUIWizDigitalSign function, by passing in a structure that contains file information, certificate details, and an optional timestamp server URL. This low-level approach allows the Publisher precise control over the signing process, including handling custom signing options and error scenarios.

The option to enable timestamping in the Publisher can be found on the Advanced tab.

Patch My PC Publisher Timestamping

An example of a signed WSUS update CAB file using the Patch My PC service with Timestamping enabled can be found below.

Timestamped CAB file

What can go wrong with Timestamping?

Several challenges can arise during the timestamping process, not limited to:-

  • CRL/OCSP Validation Failures – Blocked URLs for Certificate Revocation Lists (CRLs) or Online Certificate Status Protocol (OCSP) failures can prevent validation of the timestamping server’s certificate.
  • Timestamp Server URL Blocked – Firewalls or proxies may block access to the timestamp server, resulting in failed timestamping.
  • Invalid or Expired Server Certificate – An outdated or untrusted timestamp server certificate can cause the signature to be invalid.
  • Enforced Timestamping Policy – If timestamping is mandatory, any failure in the process will block the signature entirely.
  • System Clock Issues – An incorrect system clock can lead to validation errors or rejected timestamps.

Firewalls are the main cause of frustration when it comes to the timestamping process and it is sometime difficult to know which URLs a TSA leverages without fully understanding the response from the TSA server.

Bouncy Castle Cryptography Library

The Bouncy Castle cryptography library is a powerful tool for working with cryptographic data and standards and is especially useful when dealing with timestamping. It simplifies the process of handling cryptographic formats like ASN.1 which is essential for timestamping operations.

Using the Bouncy Castle crypto library, we can create and send requests to a timestamp server and parse and analyse the response to understand if a timestamping operation is successful. The library is critical to assist with decoding the response, which is in a complex ASN.1 format.

We can load the BouncyCastle.Crypto.dll in our PowerShell code and make some requests to a TSA and review the response.

PowerShell Example

In the example below, we take a CAB file, grab the hash and send it to the DigiCert TSA and review the response using the Bouncy Castle library.

# Load the Bouncy Castle library
$bouncyCastleDllPath = "C:\Temp\timestamptest\BouncyCastle.Crypto.dll"
Add-Type -Path $bouncyCastleDllPath

# Define variables
$filePath = "C:\Temp\timestamptest\testfile.cab"
$timestampServer = "http://timestamp.digicert.com"

# Generate file hash
$fileContent = [System.IO.File]::ReadAllBytes($filePath)
$sha256 = [System.Security.Cryptography.SHA256]::Create()
$fileHash = $sha256.ComputeHash($fileContent)

# Create timestamp request
$requestGenerator = [Org.BouncyCastle.Tsp.TimeStampRequestGenerator]::new()
$requestGenerator.SetCertReq($true)
$tsRequest = $requestGenerator.Generate("2.16.840.1.101.3.4.2.1", $fileHash)

# Send request to timestamp server
$responseBytes = Invoke-WebRequest -Uri $timestampServer -Method Post -Body $tsRequest.GetEncoded() -ContentType "application/timestamp-query"

# Parse timestamp response
$timestampResponse = [Org.BouncyCastle.Tsp.TimeStampResponse]::new($responseBytes.Content)
$timestampResponse.Validate($tsRequest)

# Extract information
$timestampToken = $timestampResponse.TimeStampToken
Write-Host "Timestamp Generated At: $($timestampToken.TimeStampInfo.GenTime)"
Write-Host "Timestamp Serial Number: $($timestampToken.TimeStampInfo.SerialNumber)"

Bouncy Castle Timestamping

The response indicates that a timestamp was retrieved successfully from the TSA.

PowerShell Solution

Combining both the SignTool from Microsoft and the Bouncy Castle library, we can create a small test environment to understand if timestamping is going to work effectively in our own environment.

The solution below will:-

  • Digitally sign a specified file by generating a self-signed code-signing certificate (certificate is saved as a pfx).
  • Applies a trusted timestamp to the signed file using a timestamp server (e.g. DigiCert TSA).
  • Extracts and saves the certificates used by the timestamp server for validation.
  • Extracts and displays the CRL (Certificate Revocation List) distribution points from the timestamp server’s certificates.
  • Ensures the integrity and authenticity of signed files for future verification.
  • Extracts additional metadata from the timestamp response, including certificate details, hash algorithm, policy OID, and serial number.

The solution can be downloaded from https://github.com/PatchMyPCTeam/Community-Scripts/blob/main/Other/Timestamping/Test-TimeStamping.ps1

Solution Requirements

Bouncy Castle Crypto DLL

The Bouncy Castle library is required for ASN.1 parsing and timestamp-related cryptographic operations. Download the BouncyCastle.Cryptography NuGet package from https://www.nuget.org/packages/BouncyCastle.Cryptography.

Extract and place the BouncyCastle.Crypto.dll in the same directory as the script.

SignTool

Signtool.exe is a part of the Windows SDK and is required for signing and timestamping files. Download the Windows SDK from https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk

After installing the SDK, locate signtool.exe in C:\Program Files (x86)\Windows Kits\10\bin\<version>\<architecture>\signtool.exe.

Place signtool.exe in the same directory as the script.

Script Parameters

The script will attempt to create a directory which will be used to generate the test files, certificates and store the timestamp server response. Explorer.exe is copied into this directory and this binary is used to make the CAB file.

    [string]$Path = 'C:\temp\timestamptest',
    [string]$TimestampServer = 'http://timestamp.digicert.com',
    [string]$TimestampCertsFolder = 'timestamp_certs',
    [string]$OriginalFileName = 'testfile',
    [string]$SignedFileName = '_signed',
    [ValidateSet('.ps1', '.cab')]
    [string]$FileExtension = '.cab',
    [string]$DummyScriptContent = "Write-Host 'Hello, World!'",
    [string]$TempPfx = 'temp_cert.pfx',
    [string]$PfxPassword = '1234',
    [string]$Store = 'CurrentUser',
    [string]$SignTool = 'signtool.exe',
    [string]$Subject = 'CN=TimeStamp Code Signing Test',
    [string]$windowsExplorerPath = "C:\Windows\explorer.exe"

Note: Running the script with the default parameters is sufficient to perform a basic test to the TSA.

The output will look something like below. As the most common cause for timestamping failure is Firewalls, we write the CRLs involved in the timestamping operation that came back in the timestamping response.

Timestamping result

The script also shows each operation which is useful to understand the flow.

Timestamping verbose

Summary

Timestamping is a crucial addition to code-signing that ensures the long-term trust and validity of digitally signed files. By embedding a timestamp from a TSA, you can protect your scripts and files against certificate expirations or revocations – Ensuring their long term validity.

If you are responsible for managing third-party applications and updates with tools like WSUS, ConfigMgr, or Intune, understanding and implementing timestamping is vital for compliance and operational reliability.

Key Takeaways

  • Timestamping matters because it extends the trustworthiness of your signed files beyond the validity of the certificate itself.
  • Tools like SignTool, PowerShell, and the Bouncy Castle library make testing and troubleshooting timestamping very easy.

Patch My PC takes security seriously. If you haven’t already seen our third party patching solutions in action, book a demo at https://patchmypc.com/schedule-live-demo.