Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TLS mutual authentication in IIS without renegotiation

Tags:

windows

iis

ssl

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:

  1. the request is not sent through a 2-way authenticated TLS connection.
  2. this adds an extra TLS session negotiation for no reason.
  3. validating that 2-way authentication is used is difficult because the 2-way authenticated handshake messages are encrypted within the initial 1-way authenticated session
  4. TLS session renegotiation has security vulnerabilities associated with it unless you do it correctly.

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?

like image 445
juhraffe Avatar asked Dec 22 '25 17:12

juhraffe


2 Answers

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

like image 70
juhraffe Avatar answered Dec 24 '25 06:12

juhraffe


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
like image 29
ambidexterous Avatar answered Dec 24 '25 07:12

ambidexterous



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!