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:
I will be addressing both IIS 7 and IIS 7.5 as IIS 7.x.
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.
Taking the above architecture into consideration this is how the IIS 6 request flow looks like:
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.
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.
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.
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:
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:
In IIS 6, this is how the bindings section looked like within the MetaBase.xml:
<IIsWebServer Location="/LM/W3SVC/1" AppPoolId="DefaultAppPool"
ServerBindings=":80: :80:www.kaushal.com :80:www.kaushal.edu :80:kaushal"
ServerComment="Default Web Site" ServerSize="1"
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:
<site name="Default Web Site" id="1" serverAutoStart="true">
<virtualDirectory path="/" physicalPath="%SystemDrive%\inetpub\wwwroot" />
<binding protocol="http" bindingInformation="*:80:" />
<binding protocol="https" bindingInformation="*:443:" sslFlags="0" />
<traceFailedRequestsLogging enabled="true" />
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.
To get the above UI:
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.
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:
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:
This can also be retrieved via command prompt by executing the following command:
netsh http show sslcert
netsh http show sslcert
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.