I'm hosting a web app that uses TLS with mutual (2-way) authentication for all connections. My web app is hosted with IIS 8 on Windows Server 2012, and it is configured within IIS to require SSL and also require a client certificate. When I access the web app from a browser I am prompted for a certificate, and everything seems fine.
However, when I look at the packet captures I see that the TLS session starts out as a 1-way authenticated session, then the request is sent, then the session is renegotiated to be a 2-way authenticated session, and then the response is sent in this 2-way authenticated session.
This is not acceptable for the following reasons:
My guess is that IIS needs to know which site you are trying to access before it can apply the appropriate SSL settings, so it starts with a "default" 1-way authenticated session, and after it receives the request it determines that it needs to use 2-way authentication. Since everything I'm hosting on IIS will require 2-way authentication I'd like this to be the "default" behavior. Is there some way to either code the web app or configure IIS (or Windows Server 2012) to always start with a 2-way authenticated TLS session?
Found the answer at http://technet.microsoft.com/en-us/security/bulletin/MS10-049. It doesn't list IIS 8, but the fix for IIS 7 seems to work:
For IIS 7:
Save the following text to a file called Enable_SSL_Renegotiate_Workaround.js
// replace 1 on this line with the number of the web site you wish to configure
var vdirObj=GetObject("IIS://localhost/W3svc/1");
WScript.Echo("Value of SSLAlwaysNegoClientCert Before: " + vdirObj.SSLAlwaysNegoClientCert);
vdirObj.Put("SSLAlwaysNegoClientCert", true);
vdirObj.SetInfo();
WScript.Echo("Value of SSLAlwaysNegoClientCert After: " + vdirObj.SSLAlwaysNegoClientCert);
Run the following command from an elevated / administrator command prompt:
cscript.exe enable_ssl_renegotiate_workaround.js
juhraffe's answer was indeed working, but also lead me to discover a following solution which seems bit cleaner.
During our deployment process, we're binding the certs to ports using the Network Configuration utility
netsh http add sslcert ipport=0.0.0.0:443 certhash=f882031933dc66a88993d5b5c326ed21b2ea8779 appid={4dc3e166-e14b-4a21-b022-59fc669b0914}
Apparently there's an extra flag tha can be added which will achive the same effect as described in juhraffe's solution
so this is how we modified the command
netsh http add sslcert ipport=0.0.0.0:443 certhash=f882031933dc66a88993d5b5c326ed21b2ea8779 appid={4dc3e166-e14b-4a21-b022-59fc669b0914} clientcertnegotiation=enable
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With