Welcome to MSDN Blogs Sign in | Join | Help

IIS7, SSL and renewal woes

As this is getting a FAQ hitting my desk about once a month now, I would like to cover the Issue, give you a solution and some background data to explain what's happening. The question at hand is: I want to renew a SSL Server certificate for my IIS7 server and use the "renew..." option in the Inetmgr GUI. The resulting file is however rejected by my Certification Authority (Verisign and GoDaddy for example). Why is that and how can I solve this?

Let's start with the solution options:

1)      Most people save the CSR they originally used. You can send that SAME CSR to the CA and will get a working certificate with new validity range. What is now left is that you need to get this certificate associated with the originally created keyset currently bound to your "old"  (near expiry or expired) certificate. Here is how to do this using the Certificates (Local Computer) MMC:

a.       Import the  new certificate into the Local Computer Personal store.

b.      Export the “old” certificate including the private key ( do NOT set the option to delete the private key on success!).

c.       Delete the “old” certificate in the MMC

d.      Use the serial number from the new certificate and run this command from an elevated cmd prompt:
certutil –repairstore my “put serial here”

e.      Assign the new certificate to the IIS website.

2)      Use the renew button and run this command on the resulting file:
certutil –split yourfile.csr
Now use the Blob0_1.p10 file this generates in your current directory as the CSR for your CA using the returned certificate in the inetmgr certificate management UI to complete the renewal.

3)      Generate a new keyset and CSR and do the enrollment as a renewal with Verisign entering the same information as before. You can do this on a new (“dummy”) web site using the inetmgr UI (to avoid any downtime) or you can use the Certificates (Local Computer) MMC following the steps in my earlier post Creating "Wildcard" Certificate Requests for IIS using the Windows Vista/Server 2008 Certificates MMC plugin .

Background Details:

Here are some tidbits you might find interesting. A certificate renewal is a bit more than just a PKCS#10 (aka CSR) blob. What is done to make this verifyable (i.e. prove that you already have an acknowledged certificate) is that that old keyset+certificate is now used to sign the PKCS#10 adding the certificate chain used for that signature to the renewal request. A PKCS#7 container is used to hold all the components including the original certificate chain and the PKCS#10 CSR.

For some reason Verisign and some other CA's stopped supporting this format. My guess is that they found it easier to just allow PKCS#10 requests and do their own checks on the renewal aspects which for them has aside from the technicalities also billing aspects they want to take care of. But again: That is just my guess.

The IIS7 GUI does however default to the standard for renewal requests and by that makes it much easier to integrated with your own PKI allowing you to do real renewals using the Microsoft Certificate Services in your Enterprise scenarios. Due to the simplicity of the available steps that allow you to adapt to the deficiencies (lack of support for renewals)  of some of the commercial certification authorities it was decided to not add a UI option to the relevant inetmgr code as the needed effort would be very high. Just think of the testing and distribution of shipping not only creating one binary but also at least one other MUI file per language supported  by Windows.

Posted by andrekl | 0 Comments

How to overcome error 0x80070490 when installing updates in Windows Vista/Server 2008

Disclaimer:
Please note that getting this error is a serious hint towards an unstable system (in my case it was caused by a faulty hard drive). While the solution steps worked fine on my system, please create and test a backup of your system before trying the below. You can easily get to the point where a complete reinstall is needed. Nevertheless this solution has saved my a couple of days despite the time invested to go through the effotr of testing my thoughts and findings.
Please also note that you should feel comfortable with using regedit. 

Having said that, lets get to it. So the issue is: You run a Windows Update check and find some updates need to be installed. Applying one or more of the updates fails with the error in the title.

Searching for help, you will likely find this and this. Going over the steps listed there did not help.
Note: In case the content expires on the locations, I have put an edited version below.

So now you have done all that and still the update doesn't work..I hope you did note that you will need to modify the script to use your localized equivalent to "Administrators" (i.e. "Administratoren" in the German Version). For me when trying to bite the bullet and using the RTM DVD to reinstall setup gave me an "Internal Error 0" response which meant that path was blocked as well. At this point it is important to understand that all system components on the 6.x versions of Windows are controlled and executed by the "Component Based Servicing" (Technet Link) Engine which uses the "TrustedInstaller" account to run and log all updates of system components.

So I decided to give the CBS logging a chance (which is on by default) and found this near the end in %windir%\logs\cbs\cbs.log:

2008-09-27 15:53:29, Error                 CBS    Failed to resolve Package: Package_for_KB905866~31bf3856ad364e35~x86~~6.0.22.0. hr: 0x80070490

 

I now went to the registry searching for the string "KB905866" starting at <HKLM\software\Microsoft\Windows\CurrentVersion\Component Based Servicing> and deleted all keys I found that had references to it.

Once done, I could install the package just fine.

I hope this description is helpful in getting your system back to life should you hit this. From my research seeing this error means that the binaries actually present on the system are not in sync with what CBS has noted. This can be a sign of malware so you should run your favorite malware scanner to ensure that your system is "clean".

Reference Content (silghtly edited for readability):

To troubleshoot this issue, I suggest we first reset permission and reinstall Windows Update Agent 3.0.
Step 1: Reset permission
================
1. Please download the subinacl.msi file from the following link and save the installation patch onto the Desktop:
http://www.microsoft.com/downloads/details.aspx?FamilyID=E8BA3E56-D8FE-4A91-93CF-ED6985E3927B&displaylang=en
2. Please go to the Desktop and double click the downloaded file.
3. Please select the C:\Windows\System32 folder as the Destination Folder during the installation. Later we will use this tool to reset the permission settings on the current machine.
Note: If UAC (User Account Control) window is prompted for permission to continue, please click Continue.
4. Click the Start Button, in the Start Search bar, type: "notepad" (without quotes) and press Enter.
5. Copy the following commands and then paste them into the opened Notepad window:
@echo off
subinacl /subkeyreg HKEY_LOCAL_MACHINE /grant=administrators=f
subinacl /subkeyreg HKEY_CURRENT_USER /grant=administrators=f
subinacl /subkeyreg HKEY_CLASSES_ROOT /grant=administrators=f
subinacl /subdirectories %SystemDrive% /grant=administrators=f
subinacl /subkeyreg HKEY_LOCAL_MACHINE /grant=system=f
subinacl /subkeyreg HKEY_CURRENT_USER /grant=system=f
subinacl /subkeyreg HKEY_CLASSES_ROOT /grant=system=f
subinacl /subdirectories %SystemDrive% /grant=system=f
@Echo =========================
@Echo Finished.
@Echo =========================
@pause
6. After pasting the above commands, please close the Notepad window. Choose Save when you are prompted to save the file. Type "reset.bat" as the file name and choose Desktop from the left panel as the save location.
7. Refer to the Desktop and right click the reset.bat file, then choose "Run as administrator."
8. You will see a DOS-like window processing.
NOTE: It may take several minutes, please be patient. When it is finished, you will be prompted with the message: "Finished, press any key to continue".
Step 2: Reinstall Windows Update Agent 3.0
===========================
1. Please download the file from the following link:
Windows Vista (32bit)
http://download.windowsupdate.com/v7/windowsupdate/redist/standalone/WindowsUpdateAgent30-x86.exe
Windows Vista (64bit)
http://download.windowsupdate.com/v7/windowsupdate/redist/standalone/WindowsUpdateAgent30-x64.exe
2. Save the file to D: drive.
Note: Please select a drive where Windows Vista was not loaded because the file cannot be launched directly from the system root directory.
3. Click Start->Run, type: "D:\WindowsUpdateAgent30-x86.exe /wuforce" (without quotations) and then press Enter to install the Windows Update
engine.
Note: There is a space between "D:\WindowsUpdateAgent30-x86.exe" and "/wuforce"
Now, let's run Windows Update again.

Posted by andrekl | 1 Comments

Creating "Wildcard" Certificate Requests for IIS using the Windows Vista/Server 2008 Certificates MMC plugin

You can use this to generate complex (as well as simple) certificate requests that satisfy pretty nice scenarios. For example, you can add the subject alternative names to the request that match all the web site names your certificate shouild  be used with. This allows you to create a "wildcard" certificate for example to use host headers with SSL/TLS. You can find the additional steps needed to setup http.sys and IIS appropriately here and here.
Notes: Most modern clients support these "wildcard" variants:

  • CN=*.domain.tld <- This is what everyone seem to understand is a wildcard cert... Well it's ONE, but not the only possibility.
  • CN=server1.domain.tld,CN=server.anotherdomain.tld <- Internet Exploere does support this since 6.0 (at least). Other browsers might not!
  • CN=primary.domain.tld; Subject Alternative Names :DNS:primary.domain.tld,DNS:another.mydomain.tld,DNS:whatever.another.domain,... <- You put the "primary name into the Subject.CN attribute and add ALL server names (includig the primary!) as a list into the list of subject alternative names. You need to ensure to add them as DNS types (there is also EMAIL for example plus  other types you also should not use for IIS scenarios).


Here are the steps. You will need to use the "Certificates (Local Computer)" MMC as an Administrator to successfuly execute the enrollment and use  the certificates and keyset for IIS.

Notes: 
If you don’t have an enterprise CA, please don’t search for the “webserver” templates info. It does not help even if it is there.
Creating a custom request is fine. Just make sure that you save it to a file at the end. -> This is the PKCS#10 CSR you need to take to the external CA.

1)      In the MMC, go to the “Personal” folder. Right click, chose all tasks-> Advanced Operations->Custom Request.

a.       Hit “next”

b.      Choose “((no template) Legacy Key” as template

c.       Request Format = PKCS #10 is default and OK.

d.      Hit “next”

e.      Click on “Details” to get  the “Properties button to show and hit that.

f.        Please go over the tabs right to left. This will ensure that you 1st take care of the important functional items before coming to your customizations.

2)      Things to check:

a.       “Private Key” tab: “Key Type” -> Mark the keyset for “Exchange” and do NOT leave it at “Signature” (which is the default).

b.      The above does not apply if you are using a CNG provider. Using a CNG provider is ok to do, but you need to make sure to use an RSA provider or the certificate / keyset will not work for IIS. Choice of the provider is a separate topic which we would need to cover separately. Choosing “legacy key will give us the “right” RSA CSP already for our needs here.

c.       “Key Options” -> Make sure to mark the private key for “allow export” to enable you to backup the completed keyset/cert  package into a PFX (aka PKCS#12) file later. Do NOT check “Strong private key protection” as that will disable the non-interactive use. Uncheck “key archival” if marked as that is a CA function not supported by the commercial CA’s (at least not unless you have a very special agreement with them). Choose the key size you want. Go with the default (1024) if you have no special requirements/recommendations.

d.      “Extensions” Tab -> “Enhanced Key Usage”:  Add the “server authentication” EKU to the list on the right side..

e.      “Subject” tab: Add a CN entry that (of course) must be set to the server name.

f.        Note: If you are using SAN, then ALL names MUST be added there. The CN in that case should be set to the most commonly used server name as some clients might not support SAN (subject alternative name).

g.       “General” tab (optional): add descriptive text that wll later show up in the list to allow easy identification.

h.      Hit “OK” to close the Properties dialog and hit “next”

i.         Enter the wanted filename (i.e. c:\iis-csr.txt) and hit “Finish”.

3)      You now have the data you need to take to the Certifiation Authority (CA), i.e. Verisign, Thawte.etc

4)      Once you get back the certificate from the Certifiation Authority, go to the same folder as before, right click and choose “all tasks” -> import…, find the file and go through the wizard with the defaults.

5)      DONE, enrolment finished. Now you can assign the cert in the IIS MMC and backup the cert+private key into a backup PFX file if wanted.

 

Posted by andrekl | 1 Comments

Windows Vista CPC shows volumes/drives as "system" unexpectedly

This one was pretty interesting. Especially the fact that there is little documentation (at the time of this writing) about the selection criteria the Complete PC Backup (CPC) uses to determine what is needed for a system recovery. On my system I expected only "C" to show but CPC did also mark "D" as system and didn't allow me to unselect it.

What I found, using Process Monitor, is, that of course it scans what volumes there are and where the boot and system files are. All of this will on most Windows Vista machines be on "C". Applications and services can be on other volumes w/o CPC marking that drive as "system". I did install Visual Studio 2008 on "D:" for organizational reasons though. This got me an easy to overlook component that took quite some to time to track down as it did not show up in the procmon trace (plus the trace is not easy to read as there is no "failure" condition).

It turns out that the profiling driver (VSPerfDrv90) was added by Visual Studio Setup and referenced via the Install path on "D": (\??\D:\Program Files\Microsoft Visual Studio 9.0\Team Tools\Performance Tools\VSPerfDrv90.sys) instead of putting it into the "common" folder VS does create for some components on the system drive.
Note: The msvcmon service is referenced the same way but as that link did not cause the same effect.

So I changed the ImagePath value of the driver to point to "C" and after a reboot CPC finally showed me what I wanted.

Posted by andrekl | 0 Comments
Filed under:

How to recover from iisadmin startup "Error 0x80090016 - NTE_BAD_KEYSET"

Here is the short version:
You need at least the 3.x package of JailBreak and a working IIS Server. The .Net Framework 2.0 (or later) must also be installed on both to give you the aspnet_regiis.exe tool.

  • On the "broken" server backup the data to enable rollback:
    From %windir%\system32\}inetsrv save the metabase.xml and the history and metaback folders
  • execute the following to save the keyset that the IISAdmin service has created last using the Jailbreak command line tool for this:
    jbcsp.exe "Microsoft Internet Information Server" IISKey-backup.xml

Update:
It has been found that aspnet_regiis doesn't export the signature keyset from the "Microsoft Internet Information Server" key container. So the steps need to be ammended by using a separate tool to get that keyset exported. Here is the code you will need to get the Jailbreak toolset to run on the "Microsoft Internet Information Server" key container.


<code name="ImportExportRSAKeys.cs">
using System;
using System.IO;
using System.Security;
using System.Security.Cryptography;
using System.Security.Cryptography.Xml;

public class Sample {
    private static void PrintUsage() {
        Console.WriteLine("Usage: ImportExportRSAKeys.exe [-exp|-imp] fileName RSA-KeyContainer-Name");
    }
    static void Main(string [] args) {
        try {
            if (args.Length < 3) {
                PrintUsage();
            } else if (args[0] == "-exp")
                DoExport(args[1], args[2]);
            else if (args[0] == "-imp")
                DoImport(args[1], args[2]);
            else {
                PrintUsage();
            }
        } catch(Exception e) {
            Console.WriteLine(e.ToString());
        }
    }

    public static void DoExport(string fileName, string containerName) {
        RSACryptoServiceProvider rsa = GetCryptoServiceProvider(containerName, true);
        string xmlString = rsa.ToXmlString(true);
        File.WriteAllText(fileName, xmlString);
        rsa.Clear();
    }


    public static void DoImport(string fileName, string containerName) {
        RSACryptoServiceProvider rsa = GetCryptoServiceProvider(containerName, false);
        rsa.FromXmlString(File.ReadAllText(fileName));
        rsa.PersistKeyInCsp = true;
        rsa.Clear();
    }


    private static RSACryptoServiceProvider GetCryptoServiceProvider(string containerName, bool keyMustExist) {
        CspParameters csp = new CspParameters();
        csp.KeyContainerName = containerName;
        csp.KeyNumber = 2; // AT_SIGNATURE

        csp.Flags |= CspProviderFlags.UseMachineKeyStore;
        if (keyMustExist)
            csp.Flags |= CspProviderFlags.UseExistingKey;

        return new RSACryptoServiceProvider(csp);
    }

}
</code> 

Now get the "good" configuration from the working server:

  • Start with saving the IIS keyset used on this machine so we can later use that on the "broken" box:
    execute the following to save the keyset that the IISAdmin service has created last:
    jbcsp.exe "Microsoft Internet Information Server" IISKey-Save.xml
  • Ensure that the IISAdmin service is stopped (net stop iisadmin /y) and then copy the IISKey-Save.xml and %windir%\system32\inetsrv\metabase.xml file from the working server to the broken machine into the %windir%\system32\inetsrv on that server.

Back on the "broken" machine:

  •  Finalize the repair by importing the keyset that does work with the metabase.xml you just copied:
    %windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_regiis.exe -pi "Microsoft Internet Information Server" %windir%\system32\inetsrv\IISKey-Save.xml –exp

Result:

net start iisadmin will now work. You will of course have to add the unique settings for the machine into the metabase.xml using the backup data but the above steps will save you from having to reinstall IIS (and the Applications that depend on it, like Exchange).

If you are interested in the details of the scenario, read on.

Please keep in mind that the XML/BIN file is only a persistence container while the real metabase you work on using the ABO/ADSI API is always acting on the in-memory representation! When moving the IIS configuration store (i.e. metabase) away from the binary format (metabase.bin in IIS5) to XML (metabase.xml in IIS6) the need to save "confidential" data appropriately didn't vanish and so the IIS team chose to use a bin2hex serialization for those entries/attributes that need to be protected while on-disk.

Obviously that itself does not address the security and so, of course, the blob persisted is encrypted. To help make this encryption fast, the IIS Setup generates a SessionKey that is used to encrypt the protected data before persisting it into the metabase file.

To protect the SessionKey itself a CAPI key pair is used that we create/use using its container name "Microsoft Internet Information Server". This key set is also created by the IISAdmin service on startup if opening the key container fails for some reason (it tries to always create if and only uses it if the error says it is already there). Using this key pair the SessionKey is encrypted and prepended by a header. Then the complete blob is signed using the same key set and the complete data construct is then serialized into the SessionKey attribute in the metabase.

As the "Microsoft Internet Information Server" key set isn't marked to allow the exporting of the private key, the resulting metabase is now bound to this machine as long as you are "playing nice". Jailbreak allows you as an administrator to overcome/override the decision and you can now export the key set.

Relevant Tools/Commands:
List all machine key sets: certutil -key
Show the details of the IIS6 key container: certutil -v -key "Microsoft Internet Information Server"
Import/export/generate CAPI key sets: aspnet_regiis.exe

Posted by andrekl | 0 Comments

Strong name signing in Visual Studio 2005 requires KeySpec=2 (AT_SIGNATURE)

I had the pleasure to troubleshoot this interesing issue and feel this information might be helpful for everyone dealing with code signing. You might hit this when trying to use the same keyset for strongname signing as well as for manifest and/or Authenticode signing.

As noted in this article Visual Studio 2005 cannot handle PKCS#12 files that hold several certificates (the CA chain). But even if you have ensured that only the end entity certificate is present in the PFX file, you might get an error dialog from Visual Studio after entering the passphrase for the FPX file:
Title: "Error during Import of the Keyset"

Message: "Object already exists"

Cause:
During enrollment (really when creating the keyset and the CSR) the KeySpec parameter has been incorrectly set to AT_KEYEXCHANGE (1). This must be AT_SIGNATURE (2) for Visual Studio 2005 to work.

Solutions:

  1. Create a new CSR with KeySpec=2 (using the Certificates MMC in Windows Vista for example) and get that signed by the CA of your choice.
    Note: Some web Enrollment Applications (Registration Authorities) seem to set the KeySpec wrongly to "1". You might want to notify CA's that do this and get this corrected.
  2. Using CertUitl from Windows Server 2003 SP1 or  later you can force KeySpec to match your wishes/needs when importing a PFX (aka PKCS#12) file. Carsten Kinder has documented the relevant options here.
    The steps to follow are:
    1. Using the "Certifiates" MMC export the existing keyset (KeySpec=1) to a PFX file.
      Note:Please backup this file to a safe location and test if the file can be imported ok on another machine if you really want to play it safe!
    2. Delete the existing certificate from the crypto store (stlll using the MMC).
    3. Open a CMD prompt.
    4. import the PFX file using this command:
      certutil -importPFX -user <pfxfilename> AT_SIGNATURE
    5. Enter the passphrase for the pfx when prompted.
    6. You now should have a keyset/Cert with KeySpec=2. If needed you can now export this into another PFX file using the MMC again.

 

Posted by andrekl | 0 Comments

Limit the List of Certification Authorities allowed for Client Authentication

This seem to be something a lot of people are interested in.
 
Problem:
On Windows Server 2003 and Windows 2000 (since the MS04-011 update) you can't use Certificate Trust Lists (CTL's) for this target.
 
Reason:
Previoously in IIS5 using the CTL wizard you could  ADD certificates to the list of allowed Certification Authorities (CA's) on top of what is already in the Local Computer Certificates store. In Windows Server 2003 / IS6 you can only limit the trust of the site to the sites in the CTL.

Example. If the root store contains CA1 and CA2, you can configure Website 1 with no IIS CTL and both CA1 and CA2 are trusted. If for WebSite 2 you create IIS CTL and add CA1, then only CA1 will be trusted for Site 2. 

Note: Using CTL's you cannot limit the list of CA's sent back to the client during the TLS handshake. I.e. you can't use CTL's to limit the list of certificates that Internet Explorer is showing. 

Solution:
What you can do though is limit the use of the CA's that are installed. Here is what you need to do.
------------------
  1. Add the "Certificates" plugin to the mmc of your choice.
  2. Point it to "Local Computer"
  3. Open up the resulting tree in the left pane and navigate to the "Trusted Root Certification Authorities\Certificates" folder.
  4. Check in the right hand pane which of the certificates show "Client Authentication" in the "Intended Purposes" column.
  5. For each of (those certificates except those you want to accept) do:
  6. {
    1. doubleclick on the certificate
    2. Go to the "Details" pane.
    3. Click on the "Edit Properties..." button.
    4. uncheck the "Client Authentication" box (You might have to click on the "Enable only the following purposes" first)
    5. Click "OK".
    6. Click "OK".
  7. }
----------------
 
Posted by andrekl | 1 Comments

Interesting problem with NavisionExample.pfx

Being back from a nice vacation in DomRep I just had an interesting issue.

Upgrading to Windows 2000 SP4 from Windows 98 or Windows Me you might see problems when using the Navision Software with the German Elster Services (used to interface with the German tax institutions). Importing the NavisionExample.Pfx (supplied for Testing ONLY!) works fine, but when you try to export the certificate you get "can't find the private key for this certificate" even though CertUI does show the "You have a private key for this certificate". The pfx works fine on newly installed machines and also on all machines running Windows XP and Windows Server 2003 (new install AND upgraded).

Solution: Make sure you install the available updates from Windowsupdate. The update from MS04-011 will provide the needed updates to handle the pfx correctly.

 

Posted by andrekl | 1 Comments

The Beginning

Hi,

this is my first entry to get started with blogging. In the future this should be filling with info mainly around IIS and PKI for now.

ciao,
  Andreas

Posted by andrekl | 0 Comments
 
Page view tracker