Cross signing an msi or executable. Is there any reason to do so? - code-signing

https://learn.microsoft.com/en-us/windows-hardware/drivers/install/cross-certificates-for-kernel-mode-code-signing
As per the link above you can sign a kernel model driver with your code signing certificate, then sign it again with the cross signed cert. This is required for a kernel mode driver.
The question is, is there any reason/benefit of signing your exe/msi packages with the cross signed certificate as well?
If there isn't any benefit, why is it required for a kernel mode driver? How does it make it more secure?

Cross signing gives an extra level of trust, which is important for kernel mode drivers. Cross signing provides extra trust because it's very unlikely that both certificate authorities would have been compromised.
For EXE's and MSI's it would seem that cross signing means your executable can still be trusted in the event that one of the authorities were compromised.
EDIT:
My personal experience related to this was with Authenticode signed assemblies and how they can be slow to load (you haven't said if your EXE is a .NET assembly). See here https://blogs.msdn.microsoft.com/shawnfa/2005/12/13/authenticode-and-assemblies/
Assembly Load Performance
When the CLR loads an assembly which has an Authenticode signature, it
will always try to verify that signature. This is in contrast to the
Windows loader, which will verify the signature of a file only in
specific instances, such as when the file is an ActiveX control. This
verification can be quite time intensive, since it can require hitting
the network several times to download up to date certificate
revocation lists, and also to ensure that there is a full chain of
valid certificates on the way to a trusted root. So, when an
Authenticode signature is applied to an assembly it's not unheard of
to see a several second delay while that assembly is being loaded.
Also note that the optimization applied to strongly named assemblies,
where the strong name signature is not verified if the assembly is
being loaded from the GAC is not applied to Authenticode signatures.
Since Authenticode provides the ability to revoke a certificate, we
cannot assume that because the assembly's Authenticode signature was
valid when it went into the GAC it will remain valid every time we
load it.
To me that's saying that if your EXE is built by .NET (ie. it's an assembly) then probably the more CA's it's signed by, the slower it might load. If it's not .NET, or an ActiveX control (or 'some instances), then there will be no delay.

Related

Why does Windows state "Unverified Publisher" for signed executable with a subsequently expired certificate

In 2014, I bought a class two code signing certificate from StartSSL which I used to digitally sign my binaries. This certificate has just expired and I actually am in the process of trying to get a new one. However, in an unrelated incident, I ran one of my signed setup programs in a VM and was somewhat ... annoyed ... when Windows brought up the "Unverified Publisher" variant of the UAC dialog.
When I view the digital signature properties I see this:
Of course the certificate has expired, but why is the file (that was signed within the validity period) suddenly unverified? I haven't seen this happen with other software, for example if I look at an old signed copy of Office 2003 setup, that doesn't complain about an invalid signature and that validaty period expired a decade ago.
Why is this? Frankly I'm now wondering what the the point of buying the certificate in the first place was and seriously considering cancelling the in-process replacement. Seems kind of pointless when they invalidate themselves. Or is this the different between class 2 and 3? (Class 3 is the version I'm trying to get hold of now)
This is apparently a by-design limitation on some code-signing certificates, as described in the first footnote to Microsoft's blog post, Everything you need to know about Authenticode Code Signing:
Not all publisher certificates are enabled to permit timestamping to provide indefinite lifetime. If the publisher’s signing certificate contains the lifetime signer OID (OID_KP_LIFETIME_SIGNING 1.3.6.1.4.1.311.10.3.13), the signature becomes invalid when the publisher’s signing certificate expires, even if the signature is timestamped. This is to free a Certificate Authority from the burden of maintaining Revocation lists (CRL, OCSP) in perpetuity.
You may wish to check whether the replacement certificate will have the same limitation, and perhaps consider an alternative vendor.

Best Code Signing Practice

I have acquired and deployed a digital code signing certificate. I have added it to the installation program for a Windows application, signing the InstallShield setup.exe file and the msi file. Everything works perfectly in the installation program.
My application is installed as a single exe file along with a complied html help file.
Is the best practice to digitally sign the exe file in addition to the Windows installation program?
Yes. You should sign the executable as well.
You should also ensure you use a time-stamp server if possible when signing too. Thus users of your application know the code came from a valid source, and the certificate was valid when it was signed. (The time-stamping means users can check the signing is valid after the expiry date of your certificate - i.e. the signature will be valid for all time.)

VeriSign Class 3 certificate not trusted by Windows?

I distribute a Windows desktop app which has all executable files digitally signed by a Verisign Class 3 Code Signing certificate. For the vast majority of users, this seems to work fine.
However a small number of users report the certificate is invalid. They say it comes up with the message "A certificate chain processed, but terminated in a root certificate which is not trusted by the trust provider". This corresponds to error code CERT_E_UNTRUSTEDROOT (0x800B0109). This has also been reported on a fully-updated Windows 7 machine. So presumably my certificate is OK, but Windows sometimes doesn't trust VeriSign certificates.
Why does Windows sometimes not trust VeriSign? Is there anything I can add to my installer (also signed) which will tell Windows to trust the certificate?
There are frequent updates of the Root Certificates which Microsoft rolls out via Windows Update, but which are tagged as "optional update". Hence not all users may have them installed and may need to install them manually. This also holds for "fully updated" machines, as the automatic installation is often set to only install "important updates", which the Root Certificate updates are not.
Depending on the type of desktop application, you may have to follow certain rules when signing, too. For example applications interacting with the Windows Security Center require essentially the same signing method as drivers. That is, the certificate chain gets embedded along with the signature (/ac switch to signtool). You can get the MSCV-VSClass3.cer applicable to VeriSign certificates here.
The process is often called cross-signing, which seems to be a misnomer. While this is one step in getting your driver binary or catalog cross-signed, the vital step is that Microsoft signs the driver (or more usually the catalog file these days), which is the actual cross-signing.

creating a key and signing executable with signtool

How would I sign a Visual C# executable?
SignTool.exe can't find a certificate.
How would I create a self signed key and certificate, and have signtool be able to see the certificate and use it?
OpenSSL and Visual Studio 2010 Express are installed. Running Windows 7 Ultimate x64.
Using SignTool.exe from Windows Driver Kit.
Using self-signed certificates for digitally signing your binaries pretty much goes against the concept of using digital certificates with programs. The basic idea is to prove the code was created by you (authenticity) and has not been modified since you released it (integrity). This must be done by using a signed certificate that is signed by a trusted Certificate Authority (CA).
With .Net, when a binary is digitally signed, it is automatically verified for integrity and authenticity during startup. While I have not personally tested this, using a self-signed certificate is probably going to cause you a great deal of problems.
If you want to digitally sign your programs, you need to invest in a code signing certificate from a CA. There are a number of companies out there that can provide this service (Verisign, Thawte), for a fee.
While the fee might seem a bit extreme in price, remember that you are not just purchasing a digital certificate but also 24/7 validation of that certificate. Any time someone starts your program it will ensure the program was written by you and that the program has not been changed since you released it.
Once you have a certificate, you can digitally sign your program by following the steps in How to: Sign Application and Deployment Manifests.
Update: If this program is strictly an internal application (limited to you or your business), you can created your own CA. Since you would be the only one running it, only you would need to validate it. The CA certificate would need to be installed as a Trusted Root Certificate on all the machines that would run the program (or if you have access to Windows Server, you could set up a real working CA).

Preventing executables with invalid Authenticode signatures from running

We publish an update patch to our software package in a single executable file. The file is signed with an Authenticode digital signature, using the certificate issued to us. The file is downloaded to Windows XP or Vista systems that our customers operate, where they run it in order to update our software.
Our PCI compliance auditor has asked us to protect against the following situation:
After downloading our executable file, a malicious person alters the file. An observant person would be able to check the properties for the file and determine that the signature is no longer valid.
The malicious person places the altered executable somewhere that an unsuspecting user could run it.
An unsuspecting user runs the altered file, releasing unspecified havoc.
The auditor contends there is a way (or ought to be a way) to prevent the file from running at all if the signature is not valid.
Do you know how this can be accomplished?
MSDN has some interesting articles about this subject:
Verifying the Signature of a PE File in C
How To Get Information from
Authenticode Signed Executables

Resources