The other day a customer of mine was trying to add an Authenticode signature with timestamp to their PowerShell scripts with PowerShell itself and its Set-AuthenticodeSignature cmdlet. He was able to sign the scripts just fine, but when using the timestamp option the cmdlet was not honoring Internet Explorer Proxy settings and the timestamping process failed.
If you have never seen how to add such a signature with PowerShell, check the following sample:
First we can create a test certificate in i.e. a cmd.exe:
c:\>makecert -n “CN=PowerShell Local Certificate Root” -a sha1 -eku 220.127.116.11.18.104.22.168.3 -r -sv root.pvk root.cer -ss Root -sr localMachine
c:\>makecert -pe -n “CN=Powershell User” -ss MY -a sha1 -eku 22.214.171.124.126.96.36.199.3 -iv root.pvk -ic root.cer
Then we can create a signature with timestamp in PowerShell:
C:\PS>$cert=Get-ChildItem -Path cert:\CurrentUser\my -CodeSigningCert
C:\PS>Set-AuthenticodeSignature -filepath c:\notepad.exe -certificate $cert -IncludeChain All -TimeStampServer “http://timestamp.globalsign.com/scripts/timstamp.dll”
Additionally, remember that we have several other ways to do Authenticode signing as I already commented here:
So my customer tried to use signtool.exe instead, with the same results: IE proxy settings are not getting used at all and they get an error like the following:
C:\Program Files\Microsoft SDKs\Windows\v6.1\Bin>signtool timestamp /v /t http://timestamp.globalsign.com/scripts/timstamp.dll c:\notepad.exe
SignTool Error: The specified timestamp server could not be reached.
SignTool Error: An error occurred while attempting to timestamp: c:\notepad.exe
Number of files successfully timestamped: 0
Number of errors: 1
Note that if we open Internet Explorer and enter http://timestamp.globalsign.com/scripts/timstamp.dll into the address bar, IE presents the credentials dialog box to send to the proxy and we can access the timestamp server without problems.
The cause of this issue is the following:
All signing methods we saw in my previous posts (SignTool, CAPICOM, etc.) end up using SignerSignEx API to sign, and SignerTimeStampEx API to timestamp the signature. The same applies to PowerShell’s Set-AuthenticodeSignature cmdlet.
SignerTimeStampEx will connect to the remote timestamp server in a very simple way, without using any proxy info or user credentials. And this is not configurable in any way.
So I’m afraid all signing methods we have at our disposal suffer from this limitation in the API.
In order to timestamp code, it is necessary to have unrestricted access to the Internet.
I hope this helps.
Alex (Alejandro Campos Magencio)