Authenticode, signing, VSTOs and what they have to do with CRLs

The topic of this post may sound a bit strange with many big words, but the reason of the topic is one..

One picture is worth a thousand words, so what I’m trying to explain is this:

image

 

Unknown publisher?? I can’t install it for users, I want to deploy it silently…

 

Scenario #2 -

 

image

image

While browsing to a website you’re getting the UAC prompt (or not able to install) an ActiveX object.

 

So let’s start with the basics – Authenticode certificate. What is it?

There are two issues that must be addressed to make the Internet a reliable source for software:

Ensuring authenticity - Assures users that they know where the code came from.

Ensuring integrity - Verifies that the code hasn't been tampered with since its publication.

Microsoft's solution to these issues is Microsoft Authenticode coupled with an infrastructure of trusted entities. Authenticode, which is based on industry standards, allows developers to include information about themselves and their code with their programs through the use of digital signatures.

While Authenticode itself cannot guarantee that signed code is safe to run, Authenticode is the mechanism by which users can be informed of whether the software publisher is participating in the infrastructure of trusted entities. Thus, Authenticode serves the needs of both software publishers and users who rely upon the Internet for the downloading of software.

In simple words Authenticode is a technology used by developers to sign their applications in order to notify end users that it was written by them. In here comes the whole idea of certificates, trusted authorities etc' which eventually gets utilized in order to make sure the signer is indeed a valid company (For example a certificate issued for the name Microsoft issued by VeriSign does insure it is indeed Microsoft, while a certificate issued for the name Microsoft issued by MyHomeCA doesn't really ensure the code was written by Microsoft.. does it?).

 

How does the certificate looks like?

Basically the certificate in question is a code signing certificate and is used for "Ensures software came from software publisher" and "Protects software from alteration after publication". As it says in the certificate usage policies:

image

That's the certificate used to sign the ActiveX or the VSTO control we have showed in the previous pictures.

 

Signed vs. Non-signed

So why do we need this certificate?

Well, let's look at IE behavior trying to install a signed ActiveX and an unsigned ActiveX:

The IE page references the cab file using the following code:

 <object name="secondobj" style='display:none' id='TestActivex'  
  classid='CLSID:A47C22B1-3CC3-45bc-801E-3FCC4FFD3E45' 
  codebase='/TestApp/mycab.cab#version=-1,-1,-1,-1'></object>

Now if mycab.cab is not signed using the Authenticode certificate the page received is:

image

image

User Account Control prompt stating the publisher is unknown. This may lead to the user declining the installation of the ActiveX component and the inability to silently install the component by using the ActiveX installer service.

As so clearly mentioned in the ActiveX installer service description - "Silent installation for unsigned controls is not supported"

On the other hand, if the mycab.cab file is signed the screen we'll see is:

image

image

Which looks much friendlier, and now that we trust the publisher it means we can use ActiveX installer service to silently install it.

 

But that's not the end of it.

Sometimes I may still receive the "unsigned" UAC prompt, although the ActiveX is properly signed. So why is that?

Windows WinTrust setting:

The WinTrust feature in windows is basically a group of code-signing and certificate management tools which applications can access in order to check for information.

This way Internet Explorer access the WinTrust APIs (thoroughly documented on MSDN) to verify whether we trust the certificate which used to sign the ActiveX or not.

The WinTrust itself has a registry setting which controls which certificates do we trust. This key is located under HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\WinTrust\Trust Providers\Software Publishing\ and the Value is State (DWORD).

The State value is a hexa-decimal flag which may represent a combination of any of the following flags:

WTPF_TRUSTTEST            0x00000020
WTPF_TESTCANBEVALID       0x00000080
WTPF_IGNOREEXPIRATION     0x00000100
WTPF_IGNOREREVOKATION     0x00000200
WTPF_OFFLINEOK_IND        0x00000400
WTPF_OFFLINEOK_COM        0x00000800
WTPF_OFFLINEOKNBU_IND     0x00001000
WTPF_OFFLINEOKNBU_COM     0x00002000
WTPF_VERIFY_V1_OFF        0x00010000
WTPF_IGNOREREVOCATIONONTS 0x00020000
WTPF_ALLOWONLYPERTRUST    0x00040000

An explanation can be found at http://msdn.microsoft.com/en-us/library/aa388197(v=VS.85).aspx

So since the default setting of this value is 23c00 which means:

WTPF_OFFLINEOK_IND        0x00000400
WTPF_OFFLINEOK_COM        0x00000800
WTPF_OFFLINEOKNBU_IND     0x00001000
WTPF_OFFLINEOKNBU_COM     0x00002000
WTPF_IGNOREREVOCATIONONTS 0x00020000

We'll be checking the Certificate Revocation List, which in turn, if not accessible will revert to the state that we do not the certificate used to sign the code (because we can't verify whether it's still a valid certificate if we can't access the CRLs).

 

This registry key is controller by an IE setting as well:

image

Unchecking the "Check for publisher's certificate revocation" will modify the State registry to a value of 23e00 which is:

WTPF_IGNOREREVOKATION 0x00000200 – This flag is added.
WTPF_OFFLINEOK_IND        0x00000400
WTPF_OFFLINEOK_COM        0x00000800
WTPF_OFFLINEOKNBU_IND     0x00001000
WTPF_OFFLINEOKNBU_COM     0x00002000
WTPF_IGNOREREVOCATIONONTS 0x00020000

So having a valid certificate without the ability to verify it's CRLs is the same as having an invalid certificate!

What's there to do with ActiveX's?

As always that depends:

Talking about production environments – you would need to troubleshoot the reason why the authenticode checks performed by WinTrust are failing and the ActiveX is not treated as signed by a trusted publisher.

Another option you may have is reducing the requirements which are used by WinTrust in order to verify the certificate.

Important: This option is only valid for test environments, reducing the WinTrust requirements will have a huge impact on your organizations security!

 

After you have verified your ActiveX is properly signed you can use the ActiveX installer policy to silently install the ActiveX for your organizations website:

image

(You can find that under Group Policy –> Machine settings –> Administrative Templates –> Windows Components –> ActiveX Installer Service)

Talking about VSTO

When discussing Authenticode in regards to VSTO we'll be using the same WinTrust functionality as we did with IE ActiveX installation with one small difference. Since VSTO is .NET application we're also relying on the .NET trust manager feature.

So trying to install an un-signed VSTO in our case resulted in the following:

image

Which makes sense.

Now – just as with Internet Explorer, if the VSTO is signed, but we weren't able to verify CRLs (and we were required based on the WinTrust policy) we will receive the same error message.

The .NET specific requirements for  signing are required under the following key:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\Security\TrustManager\PromptingLevel

Looking at our specific setting we noted that we have MyComputer set to a value of AuthenticodeRequired (REG_SZ)

image

Which (by using common sense) requires an assembly to pass the Authenticode requirements (defined by WinTrust) in order to be installed from the MyComputer zone.

This is called the Inclusion List (more information can be found at http://msdn.microsoft.com/en-us/library/bb772070.aspx).

 

So what's there to do with VSTO?

Well, the first and best option is to identify why our certificate is not passing the WinTrust requirements.

We can get information about the certificate used to sign the VSTO  manifest by just opening the manifest by using notepad and we'll be able to identify the certificate which was used in order to sign the VSTO. In our case the certificate was issued to <publisherIdentity name="CN=Michael Dubinsky, OU=Accounts, DC=w2k8r2, DC=local" issuerKeyHash="a8c0a14c4d0c3a2fc0a17c0439d4166baa3e44cf" />.

You can also use the certutil –verify option. More information on that is available at http://blogs.technet.com/b/pki/archive/2006/11/30/basic-crl-checking-with-certutil.aspx

By using this information we'll be able to see if the certificate is in our Trusted Publisher store, and whether it corresponds to all the requirements as required by WinTrust.

Another option would be to modify the Inclusion List policy (in this example I could set the Inclusion list for MyComputer Zone to Enabled).

Or, after looking at the certificate I have noted that I wasn't trusting the Certificate Authority which has generated the Trusted Publisher certificate (w2k8r2-W2K8R2DC01-CA).

image

 

Adding this CA to the Trusted Root Certificate Authorities has resolved the issue and I was able to silently install.

 

That's the story of Authenticode and digital signing.

Hopefully that would make some compatibility issues more understandable and easier to resolve.

Until next time,

Michael.