Timestamp on DigitalSignatures of a File

This topic contains 1 reply, has 2 voices, and was last updated by Profile photo of Tim Pringle Tim Pringle 1 year, 11 months ago.

  • Author
    Posts
  • #28207

    Am trying to get the Timestamp on DigitalSignatures of a File.. Have tried to use
    Get-Item
    Get-ItemProperty
    Get-AuthenticodeSignature

    but I am able to get only the file creation date. The time the file was created on the system.

    For example a patch downloaded from Microsoft, would have a Timestamp on DigitalSignatures when they released it. Am looking at getting that value/date

    Any suggestion on how I can get that.

  • #28208
    Profile photo of Tim Pringle
    Tim Pringle
    Participant

    Hey Preenesh,

    This unfortunately is something that Get-AuthenticodeSignature doesn't currently get.

    Your timing is impecable though! I had to find out how to do the same literally a couple of days ago when needing to check an AV signature filestamp date, and found something. I tried it and it works perfectly.

     function Get-AuthenticodeSignatureEx
            {
                param (
                    [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
                    [String[]]$filepath
                )
                
                $signature = @"
    [DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool CryptQueryObject(
        int dwObjectType,
        [MarshalAs(UnmanagedType.LPWStr)]string pvObject,
        int dwExpectedContentTypeFlags,
        int dwExpectedFormatTypeFlags,
        int dwFlags,
        ref int pdwMsgAndCertEncodingType,
        ref int pdwContentType,
        ref int pdwFormatType,
        ref IntPtr phCertStore,
        ref IntPtr phMsg,
        ref IntPtr ppvContext
    );
    [DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool CryptMsgGetParam(
        IntPtr hCryptMsg,
        int dwParamType,
        int dwIndex,
        byte[] pvData,
        ref int pcbData
    );
    [DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool CryptMsgClose(
        IntPtr hCryptMsg
    );
    [DllImport("crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern bool CertCloseStore(
        IntPtr hCertStore,
        int dwFlags
    );
    "@
                Add-Type -AssemblyName System.Security
                Add-Type -MemberDefinition $signature -Namespace PKI -Name Crypt32
                
                Get-AuthenticodeSignature -FilePath $filepath | ForEach-Object -Process {
                    $output = $_
                    if ($output.SignerCertificate -ne $null)
                    {
                        $pdwMsgAndCertEncodingType = 0
                        $pdwContentType = 0
                        $pdwFormatType = 0
                        [IntPtr]$phCertStore = [IntPtr]::Zero
                        [IntPtr]$phMsg = [IntPtr]::Zero
                        [IntPtr]$ppvContext = [IntPtr]::Zero
                        $return = [PKI.Crypt32]::CryptQueryObject(
                        1,
                        $output.Path,
                        16382,
                        14,
                        $null,
                        [ref]$pdwMsgAndCertEncodingType,
                        [ref]$pdwContentType,
                        [ref]$pdwFormatType,
                        [ref]$phCertStore,
                        [ref]$phMsg,
                        [ref]$ppvContext
                        )
                        $pcbData = 0
                        $return = [PKI.Crypt32]::CryptMsgGetParam($phMsg, 29, 0, $null, [ref]$pcbData)
                        $pvData = New-Object -TypeName byte[] -ArgumentList $pcbData
                        $return = [PKI.Crypt32]::CryptMsgGetParam($phMsg, 29, 0, $pvData, [ref]$pcbData)
                        $SignedCms = New-Object -TypeName Security.Cryptography.Pkcs.SignedCms
                        $SignedCms.Decode($pvData)
                        foreach ($Infos in $SignedCms.SignerInfos)
                        {
                            foreach ($CounterSignerInfos in $Infos.CounterSignerInfos)
                            {
                                $sTime = ($CounterSignerInfos.SignedAttributes | Where-Object -FilterScript {
                                    $_.Oid.Value -eq '1.2.840.113549.1.9.5'
                                }).Values | Where-Object -FilterScript {
                                    $_.SigningTime -ne $null
                                }
                            }
                        }
                        $output | Add-Member -MemberType NoteProperty -Name SigningTime -Value $sTime.SigningTime.ToLocalTime() -PassThru -Force
                        [void][PKI.Crypt32]::CryptMsgClose($phMsg)
                        [void][PKI.Crypt32]::CertCloseStore($phCertStore, 0)
                    }
                    else
                    {
                        $output
                    }
                }
            }
    
    

You must be logged in to reply to this topic.