Which Files Support Authenticode Signatures?
An interesting question came up today about the Set-AuthenticodeSignature cmdlet. It actually supports more than just .ps1 files, but what files exactly?
It turns out that this isn’t actually possible to know programmatically. Your best bet is to hard-code a list of things you know or can scrounge from the internet :) The ones I am aware of off-hand are:
.CAB, PE formats (.EXE, .DLL, etc) , .CAT, .MSI, .JAR,.OCX, .PS1, .PSM1, .PSD1, .PS1XML, .PSC1
Windows’ Authenticode infrastructure is based on plugins. All DLLs that support Authenticode signing are registered under:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Cryptography\OID\EncodingType 0\CryptSIPDllGetSignedDataMsg
Each DLL has a set of messages it needs to respond to, one of which is called IsMyFileType(). When you want to sign a file or verify the signature on a file, Windows walks along that list of registered GUIDs, asking each DLL: “Is this your file type?” If a DLL responds “Yes”, then it gets asked to verify the signature of that file.
The important point is that this decision is implemented as compiled code in the DLL, not some external mapping table.
Interesting aside:
This “ordered by GUID” enumeration of Authenticode plugins was the cause of our “RC1 Refresh” if you remember our initial V1 release. It turns out that the sample code from which we based our original Monad Authenticode DLL had a bug where it answered “Yes” to every file type. This never showed up because we had a GUID late in the chain. During the Monad-to-PowerShell rename, an obscure typo (capitalization of a single letter) caused our GUID to get registered as NULL.
Now, with a NULL GUID, our Authenticode plugin was guaranteed to be enumerated first. Since our plugin said that it understood how to manage signatures for all files on Windows, this broke MSI signing, EXE signing, DLL signing, and a bunch of other fun stuff!