Difference in IIS 6, IIS 7.x and IIS 8 with regards to SSL

There were lot of differences with regards to SSL moving from IIS 6 to IIS 7.x and then to IIS 8. IIS 6 in itself was a breaking change, however there were lot of limitations and they were addressed in higher versions. I will try to pen down as I remember them and will update the blog if I come across other changes.

Before I proceed further, for readers who are not familiar with IIS and Windows versions, this is a small info to set the stage:

  • IIS 6 (Windows Server 2003 and Windows XP 64 bit only)
  • IIS 7 (Windows Server 2008 and Windows Vista)
  • IIS 7.5 (Windows Server 2008 R2 and Windows 7)
  • IIS 8 (Windows Server 2012 and Windows 8)

I will be addressing both IIS 7 and IIS 7.5 as IIS 7.x.

Differences from architectural perspective:

One major difference between IIS 6 and the IIS 7.x was the way they would handle incoming HTTPS requests. Lets discuss how HTTPS requests were handled in IIS 6 before we proceed any further.

image

Taking the above architecture into consideration this is how the IIS 6 request flow looks like:

  1. HTTPS requests comes into SSL Queue within HTTP.SYS, which is in the KERNEL Mode.
  2. The encrypted requests is then sent to a USER Mode process called LSASS.exe for decryption. The request is decrypted using SChannel.dll loaded inside the lsass.exe process.
  3. The decrypted request is not sent back to the HTTP.SYS In the Kernel Mode.
  4. This is now placed in the corresponding Application Pool queue and then routed to corresponding worker process in USER Mode based upon which w3wp.exe a application pool queue corresponds too.
  5. The w3wp.exe generates the response and sends it back to the HTTP.SYS in the KERNEL Mode.
  6. This response is again sent to the Lsass.exe process in the user mode for encryption.
  7. After encryption, lsass.exe sends it back to the HTTP.SYS in the KERNEL mode.
  8. The encrypted response is sent back to the client.

PROBLEM 1:

During the course of the entire processing of request, there were several context switches (Whenever there is a flow of control from KERNEL MODE to USER MODE or vice versa, it is referred as a CONTEXT SWITCH).

There were 6 context switches in the above flow, out of which 4 context switches happened for encrypting and decrypting of request and response.

Context switching induces additional overhead and delays the processing of requests. This impacts the performance as this happens for every HTTPS request-response cycle.

These 4 context switches could have been avoided if the encryption and decryption happened in the KERNEL Mode. This was addressed in IIS 7 and the same was retained in later versions.

PROBLEM 2:

Another problem is the problem with host headers. Host Headers were never defined in the original SSL Specification, as they were part of the HTTP RFC and defined there. The TCP Layer never defined the Host headers for obvious reasons. Due to this, a major problem emerged & made SSL applications not scalable.

Due to the unavailability of the Host Header in the TCP layer, the incoming encrypted HTTPS request provided only IP+Port as information to HTTP.SYS. In IIS the problem was addressed by allowing only one SERVER CERTIFICATE (Certificate Hash) per IP+PORT binding. The SSL Host Header was mostly irrelevant unless the Server Certificate was either a Wild Card Certificate or a SAN Certificate.

This problem was later addressed by the IEEE by introducing Subject Name Indication (SNI). Here the host header was made available in the Client Hello,sent by the client to the serer during the initiation of the SSL Handshake.

This was implemented in IIS 8. However, it has its own set of limitations.

SOLUTION:

In IIS 6, the solution was already present in the form of KERNEL MODE SSL. However this required tweaking of a registry key and was not a ideal solution as it wasn’t used by most of the customers and was never recommended.

  • Go to the run prompt and type Regedit and click OK.
  • Navigate to and double-click the following key in the registry:
    • HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\HTTP\Parameters
  • Add the following DWORD registry key:
    • Name: EnableKernelSSL
    • Type: REG_DWORD
  • Data: Set this to 1 to use kernel-mode SSL; 0 is for user-mode SSL.

In IIS 7, KERNEL MODE SSL is the default option and this cannot be changed. The KSECDD.SYS driver is responsible for providing the cryptographic functionalities in the kernel mode.

This reduces the context switching during the request response cycle and hence improves the overall performance. Below is the improved request-response flow:

  1. HTTPS requests comes into SSL Queue within HTTP.SYS, which is in the KERNEL Mode.
  2. The encrypted request is decrypted with the help of KERNEL Mode SSL.
  3. This decrypted request is placed in the corresponding Application Pool queue and then routed to corresponding worker process in USER Mode based upon which w3wp.exe a application pool queue corresponds too.
  4. The w3wp.exe generates the response and sends it back to the HTTP.SYS in the KERNEL Mode.
  5. This response is encrypted via the KERNEL Mode SSL component.
  6. The encrypted response is sent back to the client.

As seen there is a clear performance improvement due to the reduced context switching.


In IIS 8, this problem 1 was already addressed as it was inheriting the architecture of IIS 7. However, considerable changes were made to the HTTP.SYS and the SSL functionality to incorporate SNI in the server architecture.

A new form of SSL binding called SNI bindings was introduced, which were in the form of HostName+Port.

You can read more about it here:

Differences from Configuration Perspective:

In IIS 6, this is how the bindings section looked like within the MetaBase.xml:

 <IIsWebServer Location="/LM/W3SVC/1" AppPoolId="DefaultAppPool"
 ...
 ...
 ...
 SSLCertHash="1c25a46a479813472f8d997b3ef4b699130b0737" SSLStoreName="MY"  
 SecureBindings=":443:"  
 ServerAutoStart="TRUE" 
 ServerBindings=":80: :80:www.kaushal.com :80:www.kaushal.edu :80:kaushal" 
 ServerComment="Default Web Site" ServerSize="1" 
 SslCtlIdentifier="{6A615835-58F1-4B6F-A779-3F5AE1F1F9E7}"  
 SslCtlStoreName="CA"  UseHostName="TRUE">

As seen in the above snippet of the config section, the SSL cert hash was stored within the MetaBase.xml along with the bindings information and SSL related information like SSLStoreName, SSLCtlStoreName etc.

This information was also present in the registry as well. There was supplication of efforts one could say because the user mode processes would refer the MetaBase.xml while kernel mode components would refer the registry related information.


This changed in IIS 7.x and later versions have incorporated it, all the certificate related information was moved to the registry, no cert related information is stored in the config file. Below is a snippet of the config:

 <sites>
     <site name="Default Web Site" id="1" serverAutoStart="true">
         <application path="/">
             <virtualDirectory path="/" physicalPath="%SystemDrive%\inetpub\wwwroot" />
         </application>
         ...
         ...
         ...
         <bindings>
             <binding protocol="http" bindingInformation="*:80:" />
              <binding protocol="https" bindingInformation="*:443:" sslFlags="0" /> 
         </bindings>
         <traceFailedRequestsLogging enabled="true" />
 </site>
 

As seen above lot of information has been removed from the config file. There were no duplication of efforts due to the removal of the cert related section from the config file, mainly due to KERNEL Mode SSL dependency. This reduced the size of the overall configuration file as well.

Differences from UI Perspective:

There was significant change as to what options were available in the IIS UI for the users when configuring SSL. This changed drastically from IIS 6 to IIS 7. Even the latest version of IIS, follows the same UI which was changed in IIS 7 with additions to incorporate the new functionalities.

IIS 6 UI was pretty limited. There were several problems associated with it. The UI allowed only one certificate to be bound to the site irrespective of whether there were 2 or more combinations of IP+Port. The reason for this was that the UI for specifying the IP+Port was different than the one which was used to bind the certificate. These were presented to the user as 2 different sections and hence was a problem.

image

To get the above UI:

  • Right click and go to the Web Site properties:
  • Go to the Web Site tab.
  • Under Web site identification click on Advanced…
  • Click on Add.. under Multiple identities for this Web site.

The above image is the UI to add the bindings for the web site. There is no option to choose the certificate or to specify the host header. The user can only specify the IP and Port and then he has to traverse to another section to choose the certificate for the site.

image

As shown above the UI to add a certificate is in a different tab altogether. Even if the user adds 3 distinct secureBindings, the UI allows only one certificate to be mapped to the Web site. This is because there was no way in the config to identify which bindings will use what certificate. As a result due to this, all the bindings for that site ended up using only one certificate. Not a ideal situation at all.


All these short comings were addressed in IIS 7 and this has remained as a base for the future IIS versions too. take a loot at this UI:

image

The UI is pretty simple. It allows the user to select a certificate for a corresponding IP+Port combination. The Host name section contains a textbox to specify the value, but is disabled by default (This is another shortcoming in IIS 7.x versions). This is enabled only if the certificate is a Wild Card certificate (If it’s a SAN certificate, the textbox would still remain disabled). When the user selects a certificate from the drop down list, it directly updates the registry values corresponding to the SSL binding.

Here is the registry key where the SSL bindings are stored:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\HTTP\Parameters\SslBindingInfo

This can also be retrieved via command prompt by executing the following command:

netsh http show sslcert


In IIS 8, not much was changed, but few additions and improvements were made to the overall SSL functionality. As I mentioned earlier, significant additions were made to make IIS scalable from IIS perspective, this was done by introducing SNI and CCS bindings. The above UI was improved slightly to incorporate the new additions and overcome the limitations of the previous version. The Host name text box remains enabled regardless of the certificate.

image

There are few other changes which exist moving forth from IIS 6 to IIS 7 and are not pleasant. Yes I’m referring to Client Certificates.

IIS 7 onwards there is no UI to specify Client Certificate mapping.

However, citing these problems, the configuration editor was introduced as separate download for IIS 7 (It is available by default in IIS 7.5 and later versions).

The configuration editor was a blessing in disguise for user who still use IIS Client Cert Authentication. However, the IIS 6 UI probably was better in this regards at least.

With this, I am calling an end to the lengthy blog. I will update the list as I come across other differences between these IIS versions.